4 Commits

Author SHA1 Message Date
552bf0af0a hby100japp功能,语音音量增加2 2026-02-07 09:42:16 +08:00
efad1f5a4b hby100japp功能,语音音量增加 2026-02-06 16:11:38 +08:00
f3551be093 hby100japp功能3 2026-02-06 11:50:38 +08:00
855714106e hby100japp功能3 2026-02-04 18:40:27 +08:00
21 changed files with 724 additions and 114 deletions

View File

@ -146,12 +146,6 @@
<version>3.3.1</version>
</dependency>-->
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-all-deps</artifactId>
<version>3.1.1</version>
<scope>compile</scope>
</dependency>
<!-- skywalking 整合 logback -->
<!-- <dependency>-->

View File

@ -55,6 +55,31 @@ public class AppDeviceHBY100JController extends BaseController {
return R.ok();
}
/**
* 语音播报
*
*/
@PostMapping("/voiceBroadcast")
public R<Void> voiceBroadcast(@RequestBody HBY100JVoiceBroadcastDto params) {
deviceHBY100JBizService.voiceBroadcast(params);
return R.ok();
}
@Data
public static class HBY100JVoiceBroadcastDto {
/**
* 设备ID
*/
Long deviceId;
/**
* 0 关闭, 1开启
*/
private Integer voiceBroadcast;
}
/**
* 爆闪模式
*/
@ -112,7 +137,7 @@ public class AppDeviceHBY100JController extends BaseController {
*/
private Integer voiceStrobeAlarm;
/**
* 0 公安,1消防,2应急,3交警4 市政5 铁路6 医疗7部队8 水利,9 语音
* 0 公安,1消防,2应急,3交警4 市政5 铁路6 医疗7语音
*/
private Integer mode;

View File

@ -47,22 +47,25 @@ public class HttpTtsClient {
/**
* 使用HTTP POST方式调用阿里云TTS服务生成MP3格式语音
*/
public byte[] synthesizeTextToMp3(String text) throws IOException {
public byte[] synthesizeTextToMp3(String text,String fileSuffix) throws IOException {
String endpoint = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts";
// 构建请求体
// String requestBody = String.format(
// "{\"appkey\":\"%s\",\"text\":\"%s\",\"voice\":\"zhifeng\",\"format\":\"MP3\",\"sample_rate\":24000,\"volume\":50,\"speech_rate\":0,\"pitch_rate\":0}",
// appKey,
// text.replace("\"", "\\\"")
// text.replace("\"", "\\\"")zhide
// );
String token = refreshAccessToken();
String requestBody = " {\n" +
" \"appkey\":\""+appKey+"\",\n" +
" \"voice\":\"zhide\",\n" +
" \"text\":\""+text+"\",\n" +
" \"token\":\""+token+"\",\n" +
" \"format\":\"mp3\"\n" +
" \"volume\": 100,\n" +
" \"pitch_rate\": 0,\n" +
" \"format\":\""+fileSuffix+"\"\n" +
" }";
URL url = new URL(endpoint);
@ -119,7 +122,7 @@ public class HttpTtsClient {
* 保存MP3到文件
*/
public String saveMp3ToFile(String text, String outputPath) throws IOException {
byte[] mp3Data = synthesizeTextToMp3(text);
byte[] mp3Data = synthesizeTextToMp3(text,"mp3");
try (FileOutputStream fos = new FileOutputStream(outputPath)) {
fos.write(mp3Data);

View File

@ -19,8 +19,8 @@ public class HttpTtsExample {
// 使用HTTP方式调用
HttpTtsClient httpClient = new HttpTtsClient(accessKeyId, accessKeySecret, appKey);
String text = "大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪";
String outputPath = "D:\\http_output9.mp3";
String text = "前方拥堵,请绕道而行";
String outputPath = "D:\\http_output11.mp3";
String resultFile = httpClient.saveMp3ToFile(text, outputPath);
System.out.println("MP3音频已保存至: " + resultFile);

View File

@ -14,6 +14,8 @@ import com.fuyuanshen.equipment.utils.AlibabaTTSUtil;
import com.fuyuanshen.equipment.utils.AudioProcessUtil;
import com.fuyuanshen.equipment.utils.FileHashUtil;
import com.fuyuanshen.equipment.utils.Mp3Duration;
import com.fuyuanshen.global.mqtt.utils.FfmpegVolumeUtil;
import com.fuyuanshen.global.mqtt.utils.FfmpegVolumeUtil3;
import com.fuyuanshen.system.domain.vo.SysOssVo;
import com.fuyuanshen.system.service.ISysOssService;
import lombok.RequiredArgsConstructor;
@ -30,7 +32,6 @@ import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
@ -181,7 +182,7 @@ public class AudioProcessService {
private String saveByteArrayToFile(byte[] data, String filename) throws IOException {
// 确定保存路径(可以是临时目录或指定目录)
String directory = System.getProperty("java.io.tmpdir"); // 使用系统临时目录
String directory = System.getProperty("java.io.tmpdir");// 使用系统临时目录
File dir = new File(directory);
if (!dir.exists()) {
dir.mkdirs();
@ -195,6 +196,7 @@ public class AudioProcessService {
fos.write(data);
}
return file.getAbsolutePath();
}
@ -450,33 +452,41 @@ public class AudioProcessService {
String accessKeySecret = "2F3sdoBJ08bYvJcuDgSkLnJwGXsvYH";
String appKey = "lbGuq5K5bEH4uxmT";
String savedPath = null;
String savedMp3VolumePath = null;
try {
// 使用HTTP方式调用
HttpTtsClient httpClient = new HttpTtsClient(accessKeyId, accessKeySecret, appKey);
//
byte[] mp3Data = httpClient.synthesizeTextToMp3(text);
byte[] mp3Data = httpClient.synthesizeTextToMp3(text,fileSuffix);
// byte[] mp3Data = alibabaTTSUtil.synthesizeTextToMp3(text);
SysOssVo upload = ossService.upload(mp3Data, generateRandomFileName(fileSuffix));
AppBusinessFileBo appBusinessFileBo = new AppBusinessFileBo();
savedPath = saveByteArrayToFile(mp3Data, generateRandomFileName(fileSuffix));
Integer mp3Duration = getMp3Duration2(savedPath);
appBusinessFileBo.setDuration(mp3Duration);
String directory = System.getProperty("java.io.tmpdir"); // 使用系统临时目录
String fileName = generateRandomFileName(fileSuffix);
savedMp3VolumePath = directory + "/" + fileName;
log.info("保存MP3文件: {}", savedMp3VolumePath);
FfmpegVolumeUtil.increaseMp3Volume(savedPath, savedMp3VolumePath, 12);
File file = new File(savedMp3VolumePath);
String fileHash = fileHashUtil.getFileHash(file,"SHA-256");
SysOssVo upload = ossService.updateHash(file, fileHash);
// 强制将HTTP替换为HTTPS
if (upload.getUrl() != null && upload.getUrl().startsWith("http://")) {
upload.setUrl(upload.getUrl().replaceFirst("^http://", "https://"));
}
AppBusinessFileBo appBusinessFileBo = new AppBusinessFileBo();
appBusinessFileBo.setFileId(upload.getOssId());
appBusinessFileBo.setBusinessId(deviceId);
appBusinessFileBo.setFileType(3L);
appBusinessFileBo.setCreateBy(AppLoginHelper.getUserId());
savedPath = saveByteArrayToFile(mp3Data, generateRandomFileName(fileSuffix));
if (savedPath != null) {
log.info("MP3文件已保存: {}", savedPath);
Integer mp3Duration = Mp3Duration.getMp3Duration(savedPath);
log.info("MP3文件时长: {} 秒", mp3Duration);
appBusinessFileBo.setDuration(mp3Duration);
}
appBusinessFileService.insertByBo(appBusinessFileBo);
if (upload != null) {
return upload.getUrl();
@ -484,14 +494,28 @@ public class AudioProcessService {
} catch (Exception e){
log.error("上传音频文件失败", e);
} finally {
log.info("删除临时文件: {}", savedPath);
log.info("删除savedPath临时文件: {}", savedPath);
if(savedPath != null){
deleteTempFile(new File(savedPath));
}
if(savedMp3VolumePath != null){
log.info("删除savedMp3VolumePath临时文件: {}", savedMp3VolumePath);
deleteTempFile(new File(savedMp3VolumePath));
}
}
return null;
}
private Integer getMp3Duration2(String savedPath) {
if (savedPath != null) {
log.info("MP3文件已保存: {}", savedPath);
Integer mp3Duration = Mp3Duration.getMp3Duration(savedPath);
log.info("MP3文件时长: {} 秒", mp3Duration);
return mp3Duration;
}
return 0;
}
private static final Random random = new Random();
private static final DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

View File

@ -29,13 +29,13 @@ public class FuncType13Brightness implements NewMqttMessageRule {
log.info("HBY100J警示灯LED亮度调节消息负载{}", context.getPayloadDict());
try {
// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
// context.getDeviceImei() + ":brightness";
//
// Map<String, Object> payloadDict = context.getPayloadDict();
// if (payloadDict != null) {
// RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
// }
String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
context.getDeviceImei() + ":brightness";
Map<String, Object> payloadDict = context.getPayloadDict();
if (payloadDict != null) {
RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
}
} catch (Exception e) {
log.error("HBY100J警示灯LED亮度调节失败", e);
}

View File

@ -2,15 +2,23 @@ package com.fuyuanshen.global.mqtt.rule.hby100j;
import com.alibaba.fastjson2.JSONObject;
import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.json.utils.JsonUtils;
import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.equipment.utils.map.GetAddressFromLatUtil;
import com.fuyuanshen.equipment.utils.map.LngLonUtil;
import com.fuyuanshen.global.mqtt.base.NewMqttMessageRule;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.mqtt.rule.hby100j.domin.FunctionType3LocationReport;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX;
/**
* 获取设备位置信息(设备下发返回响应数据、设备定时主动上报)
@ -34,10 +42,167 @@ public class FuncType3Location implements NewMqttMessageRule {
Map<String, Object> payloadDict = context.getPayloadDict();
if (payloadDict != null) {
RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
// RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
String jsonString = JSONObject.toJSONString(payloadDict);
FunctionType3LocationReport data = JSONObject.parseObject(jsonString, FunctionType3LocationReport.class);
FunctionType3LocationReport.Data data1 = data.getData();
if (data1 != null) {
Double latitude = data1.getLatitude();
Double longitude = data1.getLongitude();
asyncSendLocationToRedisWithFuture(context.getDeviceImei(), latitude.toString(), longitude.toString());
}
}
} catch (Exception e) {
log.error("HBY100J获取设备位置信息失败", e);
}
}
/** 位置未发生明显变化的距离阈值(米),可通过配置中心动态调整 */
private final double MOVEMENT_THRESHOLD_METER = 10.0;
/**
* 异步发送位置信息到Redis使用CompletableFuture
*
* @param deviceImei 设备IMEI
* @param latitude 纬度
* @param longitude 经度
*/
public void asyncSendLocationToRedisWithFuture(String deviceImei, String latitude, String longitude) {
try {
if (latitude == null || longitude == null) {
return;
}
if (StringUtils.isAnyBlank(deviceImei, latitude, longitude)) {
log.warn("位置上报参数为空deviceImei={}", deviceImei);
return;
}
//log.info("位置上报deviceImei={}, lat={}, lon={}", deviceImei, latitude, longitude);
// 1. 解析当前上报的经纬度
Double curLat = parseDoubleSafe(latitude.trim());
Double curLon = parseDoubleSafe(longitude.trim());
if (curLat == null || curLon == null) {
log.warn("经纬度格式错误直接更新deviceImei={}, lat={}, lon={}", deviceImei, latitude, longitude);
// doSaveLocation(deviceImei, latitude, longitude);
return;
}
// 2. 读取 Redis 中缓存的上一次位置
String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + deviceImei + DEVICE_LOCATION_KEY_PREFIX;
String cachedJson = RedisUtils.getCacheObject(redisKey);
if (StringUtils.isNotBlank(cachedJson)) {
com.alibaba.fastjson2.JSONObject cachedObj = com.alibaba.fastjson2.JSONObject.parseObject(cachedJson);
String cachedWgs84Lat = cachedObj.getString("wgs84_latitude");
String cachedWgs84Lon = cachedObj.getString("wgs84_longitude");
Double oldLat = parseDoubleSafe(cachedWgs84Lat);
Double oldLon = parseDoubleSafe(cachedWgs84Lon);
if (oldLat != null && oldLon != null) {
double distance = haversine(oldLat, oldLon, curLat, curLon);
if (distance <= MOVEMENT_THRESHOLD_METER) {
log.info("位置未发生明显变化({}米 <= {}米),不更新 RedisdeviceImei={}, lat={}, lon={}",
distance, MOVEMENT_THRESHOLD_METER, deviceImei, latitude, longitude);
return;
}
}
}
// String[] latArr = latitude.split("\\.");
// String[] lonArr = longitude.split("\\.");
// // 将位置信息存储到Redis中
// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + deviceImei + DEVICE_LOCATION_KEY_PREFIX;
// String redisObj = RedisUtils.getCacheObject(redisKey);
// JSONObject jsonOBj = JSONObject.parseObject(redisObj);
// if(jsonOBj != null){
// String str1 = latArr[0] +"."+ latArr[1].substring(0,4);
// String str2 = lonArr[0] +"."+ lonArr[1].substring(0,4);
//
// String cacheLatitude = jsonOBj.getString("wgs84_latitude");
// String cacheLongitude = jsonOBj.getString("wgs84_longitude");
// String[] latArr1 = cacheLatitude.split("\\.");
// String[] lonArr1 = cacheLongitude.split("\\.");
//
// String cacheStr1 = latArr1[0] +"."+ latArr1[1].substring(0,4);
// String cacheStr2 = lonArr1[0] +"."+ lonArr1[1].substring(0,4);
// if(str1.equals(cacheStr1) && str2.equals(cacheStr2)){
// log.info("位置信息未发生变化: device={}, lat={}, lon={}", deviceImei, latitude, longitude);
// return;
// }
// }
// 构造位置信息对象
Map<String, Object> locationInfo = new LinkedHashMap<>();
double[] doubles = LngLonUtil.gps84_To_Gcj02(Double.parseDouble(latitude), Double.parseDouble(longitude));
locationInfo.put("deviceImei", deviceImei);
locationInfo.put("latitude", doubles[0]);
locationInfo.put("longitude", doubles[1]);
locationInfo.put("wgs84_latitude", latitude);
locationInfo.put("wgs84_longitude", longitude);
String address = GetAddressFromLatUtil.getAdd(String.valueOf(doubles[1]), String.valueOf(doubles[0]));
locationInfo.put("address", address);
locationInfo.put("timestamp", System.currentTimeMillis());
String locationJson = JsonUtils.toJsonString(locationInfo);
// 存储到Redis
RedisUtils.setCacheObject(redisKey, locationJson);
// 存储到一个列表中,保留历史位置信息
// String locationHistoryKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_HISTORY_KEY_PREFIX + deviceImei;
// RedisUtils.addCacheList(locationHistoryKey, locationJson);
// RedisUtils.expire(locationHistoryKey, Duration.ofDays(90));
storeDeviceTrajectoryWithSortedSet(deviceImei, locationJson);
log.info("位置信息已异步发送到Redis: device={}, lat={}, lon={}", deviceImei, latitude, longitude);
} catch (Exception e) {
log.error("异步发送位置信息到Redis时出错: device={}, error={}", deviceImei, e.getMessage(), e);
}
}
/** 安全解析 double解析失败返回 null */
private Double parseDoubleSafe(String str) {
if (StringUtils.isBlank(str)) return null;
try {
return Double.parseDouble(str.trim());
} catch (NumberFormatException e) {
return null;
}
}
/** Haversine 公式计算两点球面距离(米) */
private double haversine(double lat1, double lon1, double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
/** 地球平均半径(米) */
double EARTH_RADIUS = 6371_393.0;
return EARTH_RADIUS * c;
}
/**
* 存储设备30天历史轨迹到Redis (使用Sorted Set)
*/
public void storeDeviceTrajectoryWithSortedSet(String deviceImei, String locationJson) {
try {
String trajectoryKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + deviceImei + DeviceRedisKeyConstants.DEVICE_LOCATION_HISTORY_KEY_PREFIX;
// String trajectoryKey = "device:trajectory:zset:" + deviceImei;
// String locationJson = JsonUtils.toJsonString(locationInfo);
long timestamp = System.currentTimeMillis();
// 添加到Sorted Set使用时间戳作为score
RedisUtils.zAdd(trajectoryKey, locationJson, timestamp);
// // 设置30天过期时间
// RedisUtils.expire(trajectoryKey, Duration.ofDays(30));
// 清理30天前的数据冗余保护
long thirtyDaysAgo = System.currentTimeMillis() - (7L * 24 * 60 * 60 * 1000);
RedisUtils.zRemoveRangeByScore(trajectoryKey, 0, thirtyDaysAgo);
} catch (Exception e) {
log.error("存储设备轨迹到Redis(ZSet)失败: device={}, error={}", deviceImei, e.getMessage(), e);
}
}
}

View File

@ -2,15 +2,21 @@ package com.fuyuanshen.global.mqtt.rule.hby100j;
import com.alibaba.fastjson2.JSONObject;
import com.fuyuanshen.common.core.constant.GlobalConstants;
import com.fuyuanshen.common.json.utils.JsonUtils;
import com.fuyuanshen.common.redis.utils.RedisUtils;
import com.fuyuanshen.global.mqtt.base.NewMqttMessageRule;
import com.fuyuanshen.global.mqtt.base.NewMqttRuleContext;
import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants;
import com.fuyuanshen.global.mqtt.rule.hby100j.domin.FunctionType4PowerStatusReport;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX;
import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX;
/**
* 获取设备电源状态(设备下发返回响应数据、设备定时主动上报)
@ -29,12 +35,32 @@ public class FuncType4PowerStatus implements NewMqttMessageRule {
log.info("HBY100J获取设备电源状态消息负载{}", context.getPayloadDict());
try {
String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
context.getDeviceImei() + ":powerStatus";
String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_STATUS_KEY_PREFIX);
// String redisKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX +
// context.getDeviceImei() + ":powerStatus";
Map<String, Object> payloadDict = context.getPayloadDict();
if (payloadDict != null) {
RedisUtils.setCacheObject(redisKey, JSONObject.toJSONString(payloadDict));
String str = JSONObject.toJSONString(payloadDict);
FunctionType4PowerStatusReport powerStatusReport =JSONObject.parseObject(str,FunctionType4PowerStatusReport.class);
FunctionType4PowerStatusReport.Data data = powerStatusReport.getData();
if(data != null){
// 构造设备状态信息对象
Map<String, Object> deviceInfo = new LinkedHashMap<>();
deviceInfo.put("batteryPercentage", data.getLevel());
deviceInfo.put("chargeState", data.getCharge());
deviceInfo.put("batteryRemainingTime", data.getBatteryRemainingTime());
// 将设备状态信息存储到Redis中
String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_STATUS_KEY_PREFIX;
String deviceInfoJson = JsonUtils.toJsonString(deviceInfo);
// 存储到Redis
RedisUtils.setCacheObject(deviceRedisKey, deviceInfoJson);
}
}
} catch (Exception e) {
log.error("HBY100J获取设备电源状态失败", e);

View File

@ -21,7 +21,7 @@ public class FuncType6VoicePlay implements NewMqttMessageRule {
@Override
public String getCommandType() {
return "HBY100_9";
return "HBY100_6";
}
@Override

View File

@ -44,6 +44,7 @@ public class FuncType12ForceAudioRequest {
/**
* 语音报警0关闭,1开启
*/
@JsonProperty("voice_strobe_alarm")
private Integer voiceStrobeAlarm;
//语音模式0公安,1消防,2应急,3交警4市政5铁路6医疗7部队8水利
private Integer mode;

View File

@ -49,12 +49,14 @@ public class FuncType5UpdateVoiceRequest {
* 2 - 紧急语音
* (具体含义需依据设备协议定义)
*/
@JsonProperty("voice_type")
private Integer voiceType;
/**
* 语音资源URLMP3等音频文件地址
* 示例http://8.129.5.250:10001/voice/01.mp3
*/
@JsonProperty("voice_resource")
private String voiceResource;
}
}

View File

@ -44,6 +44,7 @@ public class FuncType6VoicePlayRequest {
/**
* 语音报警0关闭,1开启
*/
@JsonProperty("voice_broadcast")
private Integer voiceBroadcast;
}
}

View File

@ -70,5 +70,8 @@ public class FunctionType4PowerStatusReport {
*/
@JsonProperty("12v_power")
private Integer twelveVPower;
@JsonProperty("battery_remaining_time")
private Integer batteryRemainingTime;
}
}

View File

@ -0,0 +1,139 @@
package com.fuyuanshen.global.mqtt.utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class FfmpegVolumeUtil {
/**
* 使用FFmpeg增加MP3文件的音量
*
* @param inputFilePath 输入MP3文件路径
* @param outputFilePath 输出MP3文件路径
* @param volumeGain 音量增益例如1.5表示增加50%音量2.0表示翻倍)
*/
public static void increaseMp3Volume(String inputFilePath, String outputFilePath, int volumeGain) {
boolean ffmpegAvailable = isFfmpegAvailable();
if (!ffmpegAvailable) {
System.err.println("FFmpeg未安装或未找到请安装FFmpeg并确保在系统路径中。");
return;
}
// 检查输入文件
File inputFile = new File(inputFilePath);
if (!inputFile.exists()) {
System.err.println("输入文件不存在:" + inputFilePath);
return;
}
if (!inputFile.canRead()) {
System.err.println("输入文件不可读:" + inputFilePath);
return;
}
// 创建输出目录
File outputFile = new File(outputFilePath);
File parentDir = outputFile.getParentFile();
if (parentDir != null) {
parentDir.mkdirs();
if (!parentDir.canWrite()) {
System.err.println("输出目录不可写:" + parentDir.getAbsolutePath());
return;
}
}
Process process = null;
try {
String command = String.format(
"ffmpeg -y -i \"%s\" -af \"volume=%sdB\" \"%s\"",
inputFilePath,
volumeGain,
outputFilePath
);
System.out.println("执行命令: " + command);
// 使用 ProcessBuilder 提供更好的控制
ProcessBuilder processBuilder = new ProcessBuilder("ffmpeg", "-y",
"-i", inputFilePath, "-af", "volume=" + volumeGain + "dB", outputFilePath);
processBuilder.redirectErrorStream(false);
process = processBuilder.start();
// 同时读取标准输出和错误输出
Process finalProcess = process;
Thread stdOutThread = new Thread(() -> {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(finalProcess.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println("[FFmpeg STDOUT] " + line);
}
} catch (IOException e) {
System.err.println("读取标准输出时出错: " + e.getMessage());
}finally {
finalProcess.destroy();
}
});
Process finalProcess1 = process;
Thread stdErrThread = new Thread(() -> {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(finalProcess1.getErrorStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.err.println("[FFmpeg STDERR] " + line);
}
} catch (IOException e) {
System.err.println("读取错误输出时出错: " + e.getMessage());
}finally {
finalProcess1.destroy();
}
});
stdOutThread.start();
stdErrThread.start();
int exitCode = process.waitFor();
stdOutThread.join();
stdErrThread.join();
if (exitCode == 0) {
System.out.println("音量调整成功!输出文件:" + outputFilePath);
} else {
System.err.println("FFmpeg命令执行失败退出码" + exitCode);
}
} catch (IOException | InterruptedException e) {
System.err.println("执行FFmpeg命令时发生错误: " + e.getMessage());
e.printStackTrace();
} finally {
if (process != null) {
System.out.println("已销毁进程");
process.destroy();
}
}
}
public static void main(String[] args) {
// 示例用法
String inputPath = "/app/input.mp3";
String outputPath = "/app/output17.mp3";
int volumeGain = 12;
increaseMp3Volume(inputPath, outputPath, volumeGain);
}
private static boolean isFfmpegAvailable() {
try {
Process process = Runtime.getRuntime().exec("ffmpeg -version");
int exitCode = process.waitFor();
return exitCode == 0;
} catch (Exception e) {
return false;
}
}
}

View File

@ -0,0 +1,92 @@
package com.fuyuanshen.global.mqtt.utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class FfmpegVolumeUtil3 {
/**
* 使用FFmpeg增加MP3文件的音量
*
* @param inputFilePath 输入MP3文件路径
* @param outputFilePath 输出MP3文件路径
* @param volumeGain 音量增益例如1.5表示增加50%音量2.0表示翻倍)
*/
public static void increaseMp3Volume(String inputFilePath, String outputFilePath, int volumeGain) {
boolean ffmpegAvailable = isFfmpegAvailable();
if (!ffmpegAvailable) {
System.err.println("FFmpeg未安装或未找到请安装FFmpeg并确保在系统路径中。");
return;
}
// 创建输出文件的父目录
File outputFile = new File(outputFilePath);
File parentDir = outputFile.getParentFile();
if (parentDir != null && !parentDir.exists()) {
boolean created = parentDir.mkdirs();
if (!created) {
System.err.println("无法创建输出目录:" + parentDir.getAbsolutePath());
return;
}
}
Process process = null;
try {
// 构建FFmpeg命令
String command = String.format(
"ffmpeg -y -i \"%s\" -af \"volume=%sdB\" \"%s\"",
inputFilePath,
volumeGain,
outputFilePath
);
System.out.println("执行命令: " + command);
// 执行FFmpeg命令
process = Runtime.getRuntime().exec(command);
// 读取命令执行结果
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待命令执行完成
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("音量调整成功!输出文件:" + outputFilePath);
} else {
System.err.println("FFmpeg命令执行失败退出码" + exitCode);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
} finally {
if (process != null) {
process.destroy();
}
}
}
public static void main(String[] args) {
// 示例用法
String inputPath = "/app/input.mp3";
String outputPath = "/app/output18.mp3";
int volumeGain = 12;
increaseMp3Volume(inputPath, outputPath, volumeGain);
}
private static boolean isFfmpegAvailable() {
try {
Process process = Runtime.getRuntime().exec("ffmpeg -version");
int exitCode = process.waitFor();
return exitCode == 0;
} catch (Exception e) {
return false;
}
}
}

View File

@ -97,6 +97,7 @@ public class DeviceBizService {
} else {
item.setOnlineStatus(0);
}
String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + item.getDeviceImei() + DEVICE_STATUS_KEY_PREFIX);
// 获取电量
if (StringUtils.isNotBlank(deviceStatus)) {

View File

@ -130,44 +130,72 @@ public class DeviceHBY100JBizService {
} else {
vo.setOnlineStatus(0);
}
String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX);
// 获取电量
if (StringUtils.isNotBlank(deviceStatus)) {
JSONObject jsonObject = JSONObject.parseObject(deviceStatus);
vo.setBatteryPercentage(jsonObject.getString("batteryPercentage"));
vo.setChargeState(jsonObject.getString("chargeState"));
vo.setBatteryPercentage(jsonObject.getInteger("batteryPercentage"));
vo.setChargeState(jsonObject.getInteger("chargeState"));
vo.setBatteryRemainingTime(jsonObject.getInteger("batteryRemainingTime"));
} else {
vo.setBatteryPercentage("0");
vo.setBatteryPercentage(0);
vo.setBatteryRemainingTime(0);
}
String lightModeStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_LIGHT_MODE_KEY_PREFIX);
String lightBrightnessStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX);
if (StringUtils.isNotBlank(lightBrightnessStatus)) {
vo.setLightBrightness(lightBrightnessStatus);
String reportStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + ":report");
if (StringUtils.isNotBlank(reportStatus)) {
FuncType14StatusReport report = JSONObject.parseObject(reportStatus,FuncType14StatusReport.class);
FuncType14StatusReport.Data data = report.getData();
FuncType14StatusReport.Brightness brightness = data.getBrightness();
if(brightness != null){
vo.setLightBrightness(brightness.getRed());
}
vo.setVolume(data.getVolume());
FuncType14StatusReport.LedStrobe ledStrobe = data.getLedStrobe();
if(ledStrobe != null){
vo.setStrobeFrequency(ledStrobe.getFrequency());
vo.setStrobeMode(ledStrobe.getMode());
vo.setStrobeEnable(ledStrobe.getEnable());
}
Integer voiceBroadcast = data.getVoiceBroadcast();
if(voiceBroadcast != null){
vo.setVoiceBroadcast(voiceBroadcast);
}
FuncType14StatusReport.SirenAlarm sirenAlarm = data.getSirenAlarm();
if(sirenAlarm != null){
vo.setVoiceStrobeAlarm(sirenAlarm.getEnable());
vo.setAlarmMode(sirenAlarm.getMode());
}
}
// 获取经度纬度
String locationKey = GlobalConstants.GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX;
String locationInfo = RedisUtils.getCacheObject(locationKey);
// if (StringUtils.isNotBlank(locationInfo)) {
// JSONObject jsonObject = JSONObject.parseObject(locationInfo);
// vo.setLongitude(jsonObject.get("longitude").toString());
// vo.setLatitude(jsonObject.get("latitude").toString());
// vo.setAddress((String) jsonObject.get("address"));
// }
String alarmStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_ALARM_KEY_PREFIX);
if (StringUtils.isNotBlank(alarmStatus)) {
vo.setVoiceStrobeAlarm(alarmStatus);
String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_LOCATION_KEY_PREFIX);
if (StringUtils.isNotBlank(location)) {
JSONObject jsonObject = JSONObject.parseObject(location);
vo.setLatitude(jsonObject.getString("latitude"));
vo.setLongitude(jsonObject.getString("longitude"));
vo.setAddress(jsonObject.getString("address"));
}
String lightBrightness = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX);
if (StringUtils.isNotBlank(lightBrightness)) {
vo.setLightBrightness(lightBrightness);
QueryWrapper<AppBusinessFile> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("business_id", device.getId());
queryWrapper.eq("file_type", 3);
queryWrapper.eq("use_status", 1);
List<AppBusinessFile> appBusinessFiles = appBusinessFileMapper.selectList(queryWrapper);
if(appBusinessFiles != null && appBusinessFiles.size() > 0){
AppBusinessFile appBusinessFile = appBusinessFiles.get(0);
SysOssVo sysOssVo = sysOssMapper.selectVoById(appBusinessFile.getFileId());
if(sysOssVo != null){
vo.setVoiceResource(sysOssVo.getUrl());
}
}
return vo;
}
@ -186,36 +214,22 @@ public class DeviceHBY100JBizService {
LoginUser loginUser = LoginHelper.getLoginUser();
bo.getDeviceIds().forEach(deviceId -> {
Device deviceObj = deviceMapper.selectById(deviceId);
// if (getDeviceStatus(deviceObj.getDeviceImei())) {
// throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
// }
// 语音播报
if(bo.getMode() == 9){
FuncType6VoicePlayRequest request = new FuncType6VoicePlayRequest();
request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei());
request.setFuncType("6");
request.setTimestamp(System.currentTimeMillis());
FuncType6VoicePlayRequest.Data data = new FuncType6VoicePlayRequest.Data();
data.setVoiceBroadcast(bo.getVoiceStrobeAlarm());
request.setData(data);
log.info("HBY100J更新语音参数{}", request);
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
}else{
FuncType12ForceAudioRequest request = new FuncType12ForceAudioRequest();
request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei());
request.setFuncType("12");
request.setTimestamp(System.currentTimeMillis());
FuncType12ForceAudioRequest.Data data = new FuncType12ForceAudioRequest.Data();
data.setVoiceStrobeAlarm(bo.getVoiceStrobeAlarm());
data.setMode(bo.getMode());
request.setData(data);
log.info("HBY100J更新语音参数{}", request);
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
}
FuncType12ForceAudioRequest request = new FuncType12ForceAudioRequest();
request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei());
request.setFuncType("12");
request.setTimestamp(System.currentTimeMillis());
FuncType12ForceAudioRequest.Data data = new FuncType12ForceAudioRequest.Data();
data.setVoiceStrobeAlarm(bo.getVoiceStrobeAlarm());
data.setMode(bo.getMode());
request.setData(data);
log.info("HBY100J强制报警下发设备参数{}", request);
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
// recordDeviceLog(deviceId, deviceObj.getDeviceName(), "强制报警激活", "强制报警激活", loginUser.getUserId());
});
@ -228,9 +242,9 @@ public class DeviceHBY100JBizService {
throw new ServiceException("文件不存在");
}
Device deviceObj = deviceMapper.selectById(appBusinessFileVo.getBusinessId());
// if (getDeviceStatus(deviceObj.getDeviceImei())) {
// throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
// }
if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
}
LoginUser loginUser = LoginHelper.getLoginUser();
SysOssVo sysOssVo = sysOssMapper.selectVoById(appBusinessFileVo.getFileId());
@ -264,11 +278,10 @@ public class DeviceHBY100JBizService {
}
public void strobeMode(AppDeviceHBY100JController.HBY100JStrobeModeDto params) {
log.info("HBY100J爆闪模式开启/关闭,请求参数:{}", params);
Device deviceObj = deviceMapper.selectById(params.getDeviceId());
// if (getDeviceStatus(deviceObj.getDeviceImei())) {
// throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
// }
if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
}
FuncType10StrobeModeRequest request = new FuncType10StrobeModeRequest();
request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei());
@ -285,9 +298,12 @@ public class DeviceHBY100JBizService {
public void lightAdjustment(AppDeviceHBY100JController.HBY100JLightAdjustmentDto params) {
log.info("HBY100J灯光调节请求参数{}", params);
Device deviceObj = deviceMapper.selectById(params.getDeviceId());
// if (getDeviceStatus(deviceObj.getDeviceImei())) {
// throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
// }
if (deviceObj == null) {
throw new ServiceException("设备不存在");
}
if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
}
FuncType13BrightnessRequest request = new FuncType13BrightnessRequest();
request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei());
@ -303,11 +319,13 @@ public class DeviceHBY100JBizService {
}
public void strobeFrequency(AppDeviceHBY100JController.HBY100JStrobeFrequencyDto params) {
log.info("HBY100J爆闪频率请求参数{}", params);
Device deviceObj = deviceMapper.selectById(params.getDeviceId());
// if (getDeviceStatus(deviceObj.getDeviceImei())) {
// throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
// }
if (deviceObj == null) {
throw new ServiceException("设备不存在");
}
if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
}
FuncType11FrequencyRequest request = new FuncType11FrequencyRequest();
request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei());
@ -316,16 +334,18 @@ public class DeviceHBY100JBizService {
FuncType11FrequencyRequest.Data data = new FuncType11FrequencyRequest.Data();
data.setFrequency(params.getFrequency());
request.setData(data);
log.info("HBY100J灯光调节,下发设备参数:{}", request);
log.info("HBY100J爆闪频率,下发设备参数:{}", request);
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
}
public void updateVolume(AppDeviceHBY100JController.HBY100JUpdateVolumeDto params) {
log.info("HBY100J更新音量请求参数{}", params);
Device deviceObj = deviceMapper.selectById(params.getDeviceId());
// if (getDeviceStatus(deviceObj.getDeviceImei())) {
// throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
// }
if (deviceObj == null) {
throw new ServiceException("设备不存在");
}
if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
}
FuncType9UpdateVolumeRequest request = new FuncType9UpdateVolumeRequest();
request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei());
@ -337,4 +357,24 @@ public class DeviceHBY100JBizService {
log.info("HBY100J更新音量下发设备参数{}", JSON.toJSONString(request));
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
}
public void voiceBroadcast(AppDeviceHBY100JController.HBY100JVoiceBroadcastDto params) {
Device deviceObj = deviceMapper.selectById(params.getDeviceId());
if (deviceObj == null) {
throw new ServiceException("设备不存在");
}
if (getDeviceStatus(deviceObj.getDeviceImei())) {
throw new ServiceException(deviceObj.getDeviceName() + ",设备已断开连接");
}
FuncType6VoicePlayRequest request = new FuncType6VoicePlayRequest();
request.setRequestId(GenerateIdUtil.generateNumericId());
request.setImei(deviceObj.getDeviceImei());
request.setFuncType("6");
request.setTimestamp(System.currentTimeMillis());
FuncType6VoicePlayRequest.Data data = new FuncType6VoicePlayRequest.Data();
data.setVoiceBroadcast(params.getVoiceBroadcast());
request.setData(data);
log.info("HBY100J语音播报下发设备参数{}", request);
mqttGateway.sendMsgToMqtt(buildMqttTopic(deviceObj.getDeviceImei()), 1, JSON.toJSONString(request));
}
}

View File

@ -54,10 +54,16 @@ public class AppDeviceHBY100JDetailVo implements Serializable {
private String bluetoothName;
//电量百分比
private String batteryPercentage;
/**
* 电量百分比
*/
private Integer batteryPercentage;
//充电状态0没有充电1正在充电2为已充满
private String chargeState;
/**
* 充电状态0没有充电1正在充电2为已充满
*/
private Integer chargeState;
/**
* 在线状态(0离线1在线)
@ -65,18 +71,33 @@ public class AppDeviceHBY100JDetailVo implements Serializable {
private Integer onlineStatus;
// 经度
/**
* 经度
*/
private String longitude;
// 纬度
/**
* 纬度
*/
private String latitude;
// 逆解析地址
/**
* 逆解析地址
*/
private String address;
// 亮度
private String lightBrightness;
/**
* 亮度
*/
private Integer lightBrightness;
// 音量
/**
* 音量
*/
private Integer volume;
@ -85,20 +106,40 @@ public class AppDeviceHBY100JDetailVo implements Serializable {
*/
private String voiceResource;
// 报警模式 0公安,1 消防,2应急,3交警4 市政5 铁路6 医疗7 部队8 水利,9 语音
private String alarmMode;
// 报警模式 0公安,1 消防,2应急,3交警4 市政5 铁路6 医疗7 自定义语音
/**
* 报警模式 0公安,1 消防,2应急,3交警4 市政5 铁路6 医疗7 自定义语音
*/
private Integer alarmMode;
// 强制报警开关: 0 关闭, 1开启
private String voiceStrobeAlarm;
/**
* 强制报警开关: 0 关闭, 1开启
*/
private Integer voiceStrobeAlarm;
/**
* 0 红色爆闪1 蓝色爆闪2 黄色爆闪3红色顺时针旋转爆闪4黄色顺时针旋转爆闪5红蓝顺时针旋转爆闪6 红蓝交替爆闪
*/
private Integer strobeMode;
/**
* "enable": 0爆闪关闭, 1爆闪开启
*/
private Integer strobeEnable;
/**
* 爆闪频率
*/
private Integer strobeFrequency;
/**
* 语音播报0 关闭, 1开启
*/
private Integer voiceBroadcast;
/**
* 续航时间(分钟)
*/
private Integer batteryRemainingTime;
}

View File

@ -4,6 +4,8 @@ import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
@ -67,4 +69,32 @@ public class FileHashUtil {
throw new IllegalStateException("算法 " + ALGORITHM + " 不可用", e);
}
}
/**
* 获取文件的哈希值
* // 或者使用特定算法
* String md5Hash = getFileHash(audioFile, "MD5");
* String sha256Hash = getFileHash(audioFile, "SHA-256");
* @param file 文件
* @param algorithm 哈希算法
* @return 文件的哈希值
* @throws Exception 获取文件哈希值时发生的异常
*/
public String getFileHash(File file, String algorithm) throws Exception {
MessageDigest md = MessageDigest.getInstance(algorithm);
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
md.update(buffer, 0, bytesRead);
}
}
byte[] hashBytes = md.digest();
StringBuilder sb = new StringBuilder();
for (byte b : hashBytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}

View File

@ -68,6 +68,13 @@ public interface ISysOssService {
*/
SysOssVo updateHash(MultipartFile file, String hash);
/**
* 更新文件 hash 值
*
* @param file 文件对象
* @return 匹配的 SysOssVo 列表
*/
SysOssVo updateHash(File file, String hash);
/**
* 上传 MultipartFile 到对象存储服务,并保存文件信息到数据库
*

View File

@ -226,6 +226,22 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult, hash);
}
@Override
public SysOssVo updateHash(File file, String hash) {
// 2. 先根据 hash 查库(秒传)
SysOssVo exist = baseMapper.selectByHash(hash);
if (exist != null) {
return exist;
}
String originalfileName = file.getName();
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
OssClient storage = OssFactory.instance();
UploadResult uploadResult = storage.uploadSuffix(file, suffix);
// 保存文件信息
return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult, hash);
}
/**
* 上传 MultipartFile 到对象存储服务,并保存文件信息到数据库