添加接口
This commit is contained in:
parent
7558ba1bb0
commit
9ecf371710
|
|
@ -117,6 +117,7 @@ public class ShiroConfig {
|
||||||
filterChainDefinitionMap.put("/sys/user/passwordChange", "anon");//用户更改密码
|
filterChainDefinitionMap.put("/sys/user/passwordChange", "anon");//用户更改密码
|
||||||
filterChainDefinitionMap.put("/auth/2step-code", "anon");//登录验证码
|
filterChainDefinitionMap.put("/auth/2step-code", "anon");//登录验证码
|
||||||
filterChainDefinitionMap.put("/sys/common/static/**", "anon");//图片预览 &下载文件不限制token
|
filterChainDefinitionMap.put("/sys/common/static/**", "anon");//图片预览 &下载文件不限制token
|
||||||
|
filterChainDefinitionMap.put("/sys/commonVideo/staticVideo/**", "anon");//视频预览 &下载文件不限制token
|
||||||
filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览
|
filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览
|
||||||
filterChainDefinitionMap.put("/sys/dict/getDictItems/**", "anon");//获取字典数据
|
filterChainDefinitionMap.put("/sys/dict/getDictItems/**", "anon");//获取字典数据
|
||||||
//filterChainDefinitionMap.put("/sys/common/view/**", "anon");//图片预览不限制token
|
//filterChainDefinitionMap.put("/sys/common/view/**", "anon");//图片预览不限制token
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ import org.springframework.stereotype.Service;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static java.lang.Thread.sleep;
|
import static java.lang.Thread.sleep;
|
||||||
|
|
@ -2720,7 +2722,7 @@ public class CameraInfoServiceImpl extends ServiceImpl<CameraInfoMapper, CameraI
|
||||||
sb.append("\"storageType\"").append(":").append("0").append(",");
|
sb.append("\"storageType\"").append(":").append("0").append(",");
|
||||||
if(fileName!=null&&!fileName.equals("")){
|
if(fileName!=null&&!fileName.equals("")){
|
||||||
//存储设备ID
|
//存储设备ID
|
||||||
sb.append("\"filename\"").append(":").append("\"").append(fileName).append("\",");
|
sb.append("\"fileName\"").append(":").append("\"").append(fileName).append("\",");
|
||||||
}
|
}
|
||||||
sb.append("\"startTime\"").append(":").append(cameraInfo.getStartTime()).append(",");
|
sb.append("\"startTime\"").append(":").append(cameraInfo.getStartTime()).append(",");
|
||||||
sb.append("\"endTime\"").append(":").append(cameraInfo.getEndTime()).append(",");
|
sb.append("\"endTime\"").append(":").append(cameraInfo.getEndTime()).append(",");
|
||||||
|
|
@ -2896,8 +2898,8 @@ public class CameraInfoServiceImpl extends ServiceImpl<CameraInfoMapper, CameraI
|
||||||
cameraInfo.setStartTime(startTime);
|
cameraInfo.setStartTime(startTime);
|
||||||
cameraInfo.setEndTime(endTime);
|
cameraInfo.setEndTime(endTime);
|
||||||
try {
|
try {
|
||||||
uploadToServerResult(cameraInfo);
|
String fileNameRes = uploadToServerResult(cameraInfo);
|
||||||
return "success";
|
return fileNameRes;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return "error";
|
return "error";
|
||||||
|
|
@ -2909,7 +2911,7 @@ public class CameraInfoServiceImpl extends ServiceImpl<CameraInfoMapper, CameraI
|
||||||
* @param cameraInfo
|
* @param cameraInfo
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String uploadToServerResult(CameraInfo cameraInfo){
|
public String uploadToServerResult(CameraInfo cameraInfo) throws ParseException {
|
||||||
String ftpUsername = "";
|
String ftpUsername = "";
|
||||||
String ftpPassword = "";
|
String ftpPassword = "";
|
||||||
String ftpUploadpath = "";
|
String ftpUploadpath = "";
|
||||||
|
|
@ -2951,10 +2953,18 @@ public class CameraInfoServiceImpl extends ServiceImpl<CameraInfoMapper, CameraI
|
||||||
sb.append("\"storageType\"").append(":").append("0").append(",");
|
sb.append("\"storageType\"").append(":").append("0").append(",");
|
||||||
if(fileName!=null&&!fileName.equals("")){
|
if(fileName!=null&&!fileName.equals("")){
|
||||||
//存储设备ID
|
//存储设备ID
|
||||||
sb.append("\"filename\"").append(":").append("\"").append(fileName).append("\",");
|
sb.append("\"fileName\"").append(":").append("\"").append(fileName).append("\",");
|
||||||
}
|
}
|
||||||
sb.append("\"startTime\"").append(":").append(cameraInfo.getStartTime()).append(",");
|
// 使用 SimpleDateFormat 解析
|
||||||
sb.append("\"endTime\"").append(":").append(cameraInfo.getEndTime()).append(",");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
Date date = sdf.parse(cameraInfo.getStartTime());
|
||||||
|
Date date2 = sdf.parse(cameraInfo.getEndTime());
|
||||||
|
// long startTime = date.getTime();
|
||||||
|
// long endTime = date2.getTime();
|
||||||
|
long startTime = 1765993096;
|
||||||
|
long endTime = 1765993156;
|
||||||
|
sb.append("\"startTime\"").append(":").append(startTime).append(",");
|
||||||
|
sb.append("\"endTime\"").append(":").append(endTime).append(",");
|
||||||
sb.append("\"downloadInfo\"").append(":{");
|
sb.append("\"downloadInfo\"").append(":{");
|
||||||
sb.append("\"username\"").append(":").append("\"").append(ftpUsername).append("\",");
|
sb.append("\"username\"").append(":").append("\"").append(ftpUsername).append("\",");
|
||||||
sb.append("\"password\"").append(":").append("\"").append(ftpPassword).append("\",");
|
sb.append("\"password\"").append(":").append("\"").append(ftpPassword).append("\",");
|
||||||
|
|
@ -2963,6 +2973,7 @@ public class CameraInfoServiceImpl extends ServiceImpl<CameraInfoMapper, CameraI
|
||||||
sb.append("\"ftpPort\"").append(":").append(ftpPort);
|
sb.append("\"ftpPort\"").append(":").append(ftpPort);
|
||||||
sb.append("}");
|
sb.append("}");
|
||||||
sb.append("}");
|
sb.append("}");
|
||||||
|
System.out.println("------------------"+sb.toString());
|
||||||
String res = tumsApi.uploadToServer(sb.toString());
|
String res = tumsApi.uploadToServer(sb.toString());
|
||||||
JSONObject jsonObject = new JSONObject(res);
|
JSONObject jsonObject = new JSONObject(res);
|
||||||
String errorCode = jsonObject.getStr("error_code");
|
String errorCode = jsonObject.getStr("error_code");
|
||||||
|
|
@ -2970,7 +2981,8 @@ public class CameraInfoServiceImpl extends ServiceImpl<CameraInfoMapper, CameraI
|
||||||
JSONObject result = jsonObject.getJSONObject("result");
|
JSONObject result = jsonObject.getJSONObject("result");
|
||||||
String taskId = result.getStr("taskId");
|
String taskId = result.getStr("taskId");
|
||||||
cameraInfo.setTaskId(taskId);
|
cameraInfo.setTaskId(taskId);
|
||||||
return ftpUploadpath+fileName;
|
// getUploadToServerProcess(cameraInfo);
|
||||||
|
return ftpUploadpath+"/"+fileName+".mp4";
|
||||||
}else{
|
}else{
|
||||||
String errorMsg = "";
|
String errorMsg = "";
|
||||||
try{
|
try{
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ public class CareSubDownTplinkJob implements Job {
|
||||||
|
|
||||||
QueryWrapper<CareOrdersSub> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<CareOrdersSub> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.isNull("tplink_path");
|
queryWrapper.isNull("tplink_path");
|
||||||
|
queryWrapper.eq("iz_finish","Y");
|
||||||
List<CareOrdersSub> careOrdersSubList = careOrdersSubService.list(queryWrapper);
|
List<CareOrdersSub> careOrdersSubList = careOrdersSubService.list(queryWrapper);
|
||||||
for (CareOrdersSub careOrdersSubEntity : careOrdersSubList){
|
for (CareOrdersSub careOrdersSubEntity : careOrdersSubList){
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,281 @@
|
||||||
|
package org.jeecg.modules.system.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.nu.entity.SysUploadPreEntity;
|
||||||
|
import com.nu.modules.sysconfig.ISysConfigApi;
|
||||||
|
import com.nu.utils.HttpRequestUtil;
|
||||||
|
import com.nu.utils.SafetyUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
|
import org.jeecg.common.constant.SymbolConstant;
|
||||||
|
import org.jeecg.common.exception.JeecgBootException;
|
||||||
|
import org.jeecg.common.util.CommonUtils;
|
||||||
|
import org.jeecg.common.util.filter.SsrfFileTypeFilter;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
import org.springframework.util.FileCopyUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用户表 前端控制器
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @Author scott
|
||||||
|
* @since 2018-12-20
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/sys/commonVideo")
|
||||||
|
public class CommonVideoController {
|
||||||
|
|
||||||
|
@Value(value = "${jeecg.path.upload}")
|
||||||
|
private String uploadpath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地:local minio:minio 阿里:alioss
|
||||||
|
*/
|
||||||
|
@Value(value = "${jeecg.uploadType}")
|
||||||
|
private String uploadType;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISysConfigApi sysConfigApi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
* @Author 政辉
|
||||||
|
*/
|
||||||
|
@GetMapping("/403")
|
||||||
|
public Result<?> noauth() {
|
||||||
|
return Result.error("没有权限,请联系管理员分配权限!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 把指定URL后的字符串全部截断当成参数
|
||||||
|
* 这么做是为了防止URL中包含中文或者特殊字符(/等)时,匹配不了的问题
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static String extractPathFromPattern(final HttpServletRequest request) {
|
||||||
|
String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
|
||||||
|
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
||||||
|
return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/staticVideo/**")
|
||||||
|
public void staticVideo(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
String filePath = extractPathFromPattern(request);
|
||||||
|
if (StringUtils.isEmpty(filePath) || "null".equals(filePath)) {
|
||||||
|
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 安全过滤
|
||||||
|
filePath = filePath.replace("..", "").replace("../", "");
|
||||||
|
if (filePath.endsWith(",")) {
|
||||||
|
filePath = filePath.substring(0, filePath.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安全检查
|
||||||
|
SsrfFileTypeFilter.checkDownloadFileType(filePath);
|
||||||
|
|
||||||
|
// 获取完整文件路径
|
||||||
|
String fullPath = uploadpath + File.separator + filePath;
|
||||||
|
File file = new File(fullPath);
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
response.setStatus(HttpStatus.NOT_FOUND.value());
|
||||||
|
log.error("文件[" + filePath + "]不存在");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取请求头信息
|
||||||
|
String rangeHeader = request.getHeader("Range");
|
||||||
|
long fileLength = file.length();
|
||||||
|
|
||||||
|
// 根据文件扩展名设置 Content-Type
|
||||||
|
String contentType = getContentType(filePath);
|
||||||
|
response.setContentType(contentType);
|
||||||
|
|
||||||
|
// 如果是视频文件,支持范围请求
|
||||||
|
if (isVideoFile(filePath) && rangeHeader != null && rangeHeader.startsWith("bytes=")) {
|
||||||
|
// 处理视频流范围请求
|
||||||
|
handleRangeRequest(file, rangeHeader, fileLength, response);
|
||||||
|
} else {
|
||||||
|
// 普通文件下载(支持音频、图片等)
|
||||||
|
response.setContentType(contentType);
|
||||||
|
response.setHeader("Content-Disposition", "inline; filename=\"" +
|
||||||
|
new String(file.getName().getBytes("UTF-8"), "ISO-8859-1") + "\"");
|
||||||
|
response.setHeader("Accept-Ranges", "bytes");
|
||||||
|
response.setHeader("Content-Length", String.valueOf(fileLength));
|
||||||
|
|
||||||
|
try (InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||||
|
OutputStream outputStream = response.getOutputStream()) {
|
||||||
|
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("处理文件失败: " + filePath, e);
|
||||||
|
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("预览文件失败", e);
|
||||||
|
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理视频范围请求(支持断点续传)
|
||||||
|
*/
|
||||||
|
private void handleRangeRequest(File file, String rangeHeader, long fileLength,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
|
||||||
|
// 解析范围请求
|
||||||
|
String[] ranges = rangeHeader.substring(6).split("-");
|
||||||
|
long start = Long.parseLong(ranges[0]);
|
||||||
|
long end = (ranges.length > 1 && !ranges[1].isEmpty()) ?
|
||||||
|
Long.parseLong(ranges[1]) : fileLength - 1;
|
||||||
|
|
||||||
|
// 确保范围有效
|
||||||
|
if (start < 0) start = 0;
|
||||||
|
if (end >= fileLength) end = fileLength - 1;
|
||||||
|
|
||||||
|
long contentLength = end - start + 1;
|
||||||
|
|
||||||
|
// 设置响应头
|
||||||
|
response.setStatus(HttpStatus.PARTIAL_CONTENT.value());
|
||||||
|
response.setHeader("Content-Range", String.format("bytes %d-%d/%d", start, end, fileLength));
|
||||||
|
response.setHeader("Accept-Ranges", "bytes");
|
||||||
|
response.setHeader("Content-Length", String.valueOf(contentLength));
|
||||||
|
|
||||||
|
try (RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||||
|
OutputStream outputStream = response.getOutputStream()) {
|
||||||
|
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
raf.seek(start);
|
||||||
|
|
||||||
|
long bytesToRead = contentLength;
|
||||||
|
int bytesRead;
|
||||||
|
|
||||||
|
while (bytesToRead > 0 &&
|
||||||
|
(bytesRead = raf.read(buffer, 0, (int) Math.min(buffer.length, bytesToRead))) != -1) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead);
|
||||||
|
bytesToRead -= bytesRead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件扩展名获取 Content-Type
|
||||||
|
*/
|
||||||
|
private String getContentType(String filePath) {
|
||||||
|
String extension = getFileExtension(filePath).toLowerCase();
|
||||||
|
|
||||||
|
Map<String, String> contentTypeMap = new HashMap<>();
|
||||||
|
contentTypeMap.put("mp4", "video/mp4");
|
||||||
|
contentTypeMap.put("webm", "video/webm");
|
||||||
|
contentTypeMap.put("ogg", "video/ogg");
|
||||||
|
contentTypeMap.put("avi", "video/x-msvideo");
|
||||||
|
contentTypeMap.put("mov", "video/quicktime");
|
||||||
|
contentTypeMap.put("wmv", "video/x-ms-wmv");
|
||||||
|
contentTypeMap.put("flv", "video/x-flv");
|
||||||
|
contentTypeMap.put("mkv", "video/x-matroska");
|
||||||
|
|
||||||
|
// 音频文件
|
||||||
|
contentTypeMap.put("mp3", "audio/mpeg");
|
||||||
|
contentTypeMap.put("wav", "audio/wav");
|
||||||
|
contentTypeMap.put("ogg", "audio/ogg");
|
||||||
|
contentTypeMap.put("aac", "audio/aac");
|
||||||
|
contentTypeMap.put("flac", "audio/flac");
|
||||||
|
|
||||||
|
// 图片文件
|
||||||
|
contentTypeMap.put("jpg", "image/jpeg");
|
||||||
|
contentTypeMap.put("jpeg", "image/jpeg");
|
||||||
|
contentTypeMap.put("png", "image/png");
|
||||||
|
contentTypeMap.put("gif", "image/gif");
|
||||||
|
contentTypeMap.put("bmp", "image/bmp");
|
||||||
|
contentTypeMap.put("webp", "image/webp");
|
||||||
|
contentTypeMap.put("svg", "image/svg+xml");
|
||||||
|
|
||||||
|
// 文档文件
|
||||||
|
contentTypeMap.put("pdf", "application/pdf");
|
||||||
|
contentTypeMap.put("txt", "text/plain");
|
||||||
|
contentTypeMap.put("html", "text/html");
|
||||||
|
|
||||||
|
return contentTypeMap.getOrDefault(extension, "application/octet-stream");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为视频文件
|
||||||
|
*/
|
||||||
|
private boolean isVideoFile(String filePath) {
|
||||||
|
String extension = getFileExtension(filePath).toLowerCase();
|
||||||
|
Set<String> videoExtensions = Set.of(
|
||||||
|
"mp4", "webm", "ogg", "avi", "mov",
|
||||||
|
"wmv", "flv", "mkv", "m3u8", "ts"
|
||||||
|
);
|
||||||
|
return videoExtensions.contains(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为音频文件
|
||||||
|
*/
|
||||||
|
private boolean isAudioFile(String filePath) {
|
||||||
|
String extension = getFileExtension(filePath).toLowerCase();
|
||||||
|
Set<String> audioExtensions = Set.of(
|
||||||
|
"mp3", "wav", "ogg", "aac", "flac",
|
||||||
|
"m4a", "wma", "opus"
|
||||||
|
);
|
||||||
|
return audioExtensions.contains(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为图片文件
|
||||||
|
*/
|
||||||
|
private boolean isImageFile(String filePath) {
|
||||||
|
String extension = getFileExtension(filePath).toLowerCase();
|
||||||
|
Set<String> imageExtensions = Set.of(
|
||||||
|
"jpg", "jpeg", "png", "gif", "bmp",
|
||||||
|
"webp", "svg", "ico", "tiff"
|
||||||
|
);
|
||||||
|
return imageExtensions.contains(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件扩展名
|
||||||
|
*/
|
||||||
|
private String getFileExtension(String filePath) {
|
||||||
|
int dotIndex = filePath.lastIndexOf('.');
|
||||||
|
if (dotIndex > 0 && dotIndex < filePath.length() - 1) {
|
||||||
|
return filePath.substring(dotIndex + 1);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue