Commit 2c470f5061de91a1330c3c802d00f2bc48cdeb19

Authored by 648540858
1 parent 2adf2459

升级spring boot版本;全局异常处理;统一返回结果

... ... @@ -5,7 +5,7 @@
5 5 <parent>
6 6 <groupId>org.springframework.boot</groupId>
7 7 <artifactId>spring-boot-starter-parent</artifactId>
8   - <version>2.3.5.RELEASE</version>
  8 + <version>2.7.2</version>
9 9 </parent>
10 10 <groupId>top.panll.assist</groupId>
11 11 <artifactId>wvp-pro-assist</artifactId>
... ... @@ -56,17 +56,16 @@
56 56 <version>1.2.73</version>
57 57 </dependency>
58 58  
59   - <!--Swagger3 -->
60 59 <!--在线文档 -->
61 60 <dependency>
62   - <groupId>io.springfox</groupId>
63   - <artifactId>springfox-boot-starter</artifactId>
64   - <version>3.0.0</version>
  61 + <groupId>org.springdoc</groupId>
  62 + <artifactId>springdoc-openapi-ui</artifactId>
  63 + <version>1.6.10</version>
65 64 </dependency>
66 65 <dependency>
67 66 <groupId>com.github.xiaoymin</groupId>
68   - <artifactId>knife4j-spring-boot-starter</artifactId>
69   - <version>3.0.2</version>
  67 + <artifactId>knife4j-springdoc-ui</artifactId>
  68 + <version>3.0.3</version>
70 69 </dependency>
71 70  
72 71 <dependency>
... ...
src/main/java/top/panll/assist/config/GlobalExceptionHandler.java 0 → 100644
  1 +package top.panll.assist.config;
  2 +
  3 +import org.slf4j.Logger;
  4 +import org.slf4j.LoggerFactory;
  5 +import org.springframework.http.HttpStatus;
  6 +import org.springframework.web.bind.annotation.ExceptionHandler;
  7 +import org.springframework.web.bind.annotation.ResponseStatus;
  8 +import org.springframework.web.bind.annotation.RestControllerAdvice;
  9 +import top.panll.assist.controller.bean.ControllerException;
  10 +import top.panll.assist.controller.bean.ErrorCode;
  11 +import top.panll.assist.controller.bean.WVPResult;
  12 +
  13 +/**
  14 + * 全局异常处理
  15 + */
  16 +@RestControllerAdvice
  17 +public class GlobalExceptionHandler {
  18 +
  19 + private final static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
  20 +
  21 + /**
  22 + * 默认异常处理
  23 + * @param e 异常
  24 + * @return 统一返回结果
  25 + */
  26 + @ExceptionHandler(Exception.class)
  27 + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  28 + public WVPResult<String> exceptionHandler(Exception e) {
  29 + logger.error("[全局异常]: ", e);
  30 + return WVPResult.fail(ErrorCode.ERROR500.getCode(), e.getMessage());
  31 + }
  32 +
  33 + /**
  34 + * 自定义异常处理, 处理controller中返回的错误
  35 + * @param e 异常
  36 + * @return 统一返回结果
  37 + */
  38 + @ExceptionHandler(ControllerException.class)
  39 + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  40 + public WVPResult<String> exceptionHandler(ControllerException e) {
  41 + return WVPResult.fail(e.getCode(), e.getMsg());
  42 + }
  43 +
  44 +}
... ...
src/main/java/top/panll/assist/config/GlobalResponseAdvice.java 0 → 100644
  1 +package top.panll.assist.config;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import org.springframework.core.MethodParameter;
  5 +import org.springframework.http.MediaType;
  6 +import org.springframework.http.converter.HttpMessageConverter;
  7 +import org.springframework.http.server.ServerHttpRequest;
  8 +import org.springframework.http.server.ServerHttpResponse;
  9 +import org.springframework.web.bind.annotation.RestControllerAdvice;
  10 +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
  11 +import top.panll.assist.controller.bean.ErrorCode;
  12 +import top.panll.assist.controller.bean.WVPResult;
  13 +
  14 +import javax.validation.constraints.NotNull;
  15 +
  16 +/**
  17 + * 全局统一返回结果
  18 + * @author lin
  19 + */
  20 +@RestControllerAdvice
  21 +public class GlobalResponseAdvice implements ResponseBodyAdvice<Object> {
  22 +
  23 +
  24 + @Override
  25 + public boolean supports(@NotNull MethodParameter returnType, @NotNull Class<? extends HttpMessageConverter<?>> converterType) {
  26 + return true;
  27 + }
  28 +
  29 + @Override
  30 + public Object beforeBodyWrite(Object body, @NotNull MethodParameter returnType, @NotNull MediaType selectedContentType, @NotNull Class<? extends HttpMessageConverter<?>> selectedConverterType, @NotNull ServerHttpRequest request, @NotNull ServerHttpResponse response) {
  31 + // 排除api文档的接口,这个接口不需要统一
  32 + String[] excludePath = {"/v3/api-docs","/api/v1","/index/hook"};
  33 + for (String path : excludePath) {
  34 + if (request.getURI().getPath().startsWith(path)) {
  35 + return body;
  36 + }
  37 + }
  38 +
  39 + if (body instanceof WVPResult) {
  40 + return body;
  41 + }
  42 +
  43 + if (body instanceof ErrorCode) {
  44 + ErrorCode errorCode = (ErrorCode) body;
  45 + return new WVPResult<>(errorCode.getCode(), errorCode.getMsg(), null);
  46 + }
  47 +
  48 + if (body instanceof String) {
  49 + return JSON.toJSONString(WVPResult.success(body));
  50 + }
  51 +
  52 + return WVPResult.success(body);
  53 + }
  54 +}
... ...
src/main/java/top/panll/assist/config/SpringDocConfig.java 0 → 100644
  1 +package top.panll.assist.config;
  2 +
  3 +import io.swagger.v3.oas.models.OpenAPI;
  4 +import io.swagger.v3.oas.models.info.Contact;
  5 +import io.swagger.v3.oas.models.info.Info;
  6 +import io.swagger.v3.oas.models.info.License;
  7 +import org.springdoc.core.GroupedOpenApi;
  8 +import org.springframework.beans.factory.annotation.Value;
  9 +import org.springframework.context.annotation.Bean;
  10 +import org.springframework.context.annotation.Configuration;
  11 +
  12 +/**
  13 + * @author lin
  14 + */
  15 +@Configuration
  16 +public class SpringDocConfig {
  17 +
  18 + @Value("${doc.enabled: true}")
  19 + private boolean enable;
  20 +
  21 + @Bean
  22 + public OpenAPI springShopOpenApi() {
  23 + Contact contact = new Contact();
  24 + contact.setName("pan");
  25 + contact.setEmail("648540858@qq.com");
  26 + return new OpenAPI()
  27 + .info(new Info().title("WVP-PRO-ASSIST 接口文档")
  28 + .contact(contact)
  29 + .description("WVP-PRO助手,补充ZLM功能")
  30 + .version("v2.0")
  31 + .license(new License().name("Apache 2.0").url("http://springdoc.org")));
  32 + }
  33 +
  34 + /**
  35 + * 添加分组
  36 + * @return
  37 + */
  38 + @Bean
  39 + public GroupedOpenApi publicApi() {
  40 + return GroupedOpenApi.builder()
  41 + .group("1. 全部")
  42 + .packagesToScan("top.panll.assist")
  43 + .build();
  44 + }
  45 +}
... ...
src/main/java/top/panll/assist/config/Swagger3Config.java deleted 100644 → 0
1   -package top.panll.assist.config;
2   -
3   -import org.springframework.beans.factory.annotation.Value;
4   -import org.springframework.context.annotation.Bean;
5   -import org.springframework.context.annotation.Configuration;
6   -import springfox.documentation.builders.ApiInfoBuilder;
7   -import springfox.documentation.builders.PathSelectors;
8   -import springfox.documentation.builders.RequestHandlerSelectors;
9   -import springfox.documentation.service.ApiInfo;
10   -import springfox.documentation.service.Contact;
11   -import springfox.documentation.spi.DocumentationType;
12   -import springfox.documentation.spring.web.plugins.Docket;
13   -
14   -@Configuration
15   -public class Swagger3Config {
16   -
17   - @Value("${swagger-ui.enabled}")
18   - private boolean enable;
19   -
20   - @Bean
21   - public Docket createRestApi() {
22   - return new Docket(DocumentationType.OAS_30)
23   - .apiInfo(apiInfo())
24   - .groupName("1. 全部")
25   - .select()
26   - .apis(RequestHandlerSelectors.basePackage("top.panll.assist"))
27   - .paths(PathSelectors.any())
28   - .build()
29   - .pathMapping("/")
30   - .enable(enable);
31   - }
32   -
33   - private ApiInfo apiInfo() {
34   - return new ApiInfoBuilder()
35   - .title("WVP-PRO-ASSIST 接口文档")
36   - .description("更多请咨询服务开发者(https://github.com/648540858/wvp-pro-assist)。")
37   - .contact(new Contact("648540858", "648540858", "648540858@qq.com"))
38   - .version("1.0")
39   - .build();
40   - }
41   -}
src/main/java/top/panll/assist/controller/RecordController.java
... ... @@ -2,16 +2,17 @@ package top.panll.assist.controller;
2 2  
3 3 import com.alibaba.fastjson.JSON;
4 4 import com.alibaba.fastjson.JSONObject;
5   -import io.swagger.annotations.Api;
6   -import io.swagger.annotations.ApiImplicitParam;
7   -import io.swagger.annotations.ApiImplicitParams;
8   -import io.swagger.annotations.ApiOperation;
  5 +import io.swagger.v3.oas.annotations.Operation;
  6 +import io.swagger.v3.oas.annotations.Parameter;
  7 +import io.swagger.v3.oas.annotations.tags.Tag;
9 8 import org.slf4j.Logger;
10 9 import org.slf4j.LoggerFactory;
11 10 import org.springframework.beans.factory.annotation.Autowired;
12 11 import org.springframework.http.HttpStatus;
13 12 import org.springframework.http.ResponseEntity;
14 13 import org.springframework.web.bind.annotation.*;
  14 +import top.panll.assist.controller.bean.ControllerException;
  15 +import top.panll.assist.controller.bean.ErrorCode;
15 16 import top.panll.assist.controller.bean.WVPResult;
16 17 import top.panll.assist.dto.MergeOrCutTaskInfo;
17 18 import top.panll.assist.dto.SignInfo;
... ... @@ -28,7 +29,7 @@ import java.util.ArrayList;
28 29 import java.util.Date;
29 30 import java.util.List;
30 31 import java.util.Map;
31   -@Api(tags = "录像管理")
  32 +@Tag(name = "录像管理", description = "录像管理")
32 33 @CrossOrigin
33 34 @RestController
34 35 @RequestMapping("/api/record")
... ... @@ -49,40 +50,31 @@ public class RecordController {
49 50 * 获取app+stream列表
50 51 * @return
51 52 */
52   - @ApiOperation("分页获取app+stream的列表")
53   - @ApiImplicitParams({
54   - @ApiImplicitParam(name="page", value = "当前页", required = true, dataTypeClass = Integer.class),
55   - @ApiImplicitParam(name="count", value = "每页查询数量", required = true, dataTypeClass = Integer.class),
56   - })
  53 + @Operation(summary ="分页获取app+stream的列表")
  54 + @Parameter(name = "page", description = "当前页", required = true)
  55 + @Parameter(name = "count", description = "每页查询数量", required = true)
57 56 @GetMapping(value = "/list")
58 57 @ResponseBody
59   - public WVPResult<PageInfo<Map<String, String>>> getList(@RequestParam int page,
  58 + public PageInfo<Map<String, String>> getList(@RequestParam int page,
60 59 @RequestParam int count){
61   - WVPResult<PageInfo<Map<String, String>>> result = new WVPResult<>();
62 60 List<Map<String, String>> appList = videoFileService.getList();
63   - result.setCode(0);
64   - result.setMsg("success");
65 61  
66 62 PageInfo<Map<String, String>> stringPageInfo = new PageInfo<>(appList);
67 63 stringPageInfo.startPage(page, count);
68   - result.setData(stringPageInfo);
69   - return result;
  64 + return stringPageInfo;
70 65 }
71 66  
72 67 /**
73 68 * 分页获取app列表
74 69 * @return
75 70 */
76   - @ApiOperation("分页获取app列表")
77   - @ApiImplicitParams({
78   - @ApiImplicitParam(name="page", value = "当前页", required = true, dataTypeClass = Integer.class),
79   - @ApiImplicitParam(name="count", value = "每页查询数量", required = true, dataTypeClass = Integer.class),
80   - })
  71 + @Operation(summary ="分页获取app列表")
  72 + @Parameter(name = "page", description = "当前页", required = true)
  73 + @Parameter(name = "count", description = "每页查询数量", required = true)
81 74 @GetMapping(value = "/app/list")
82 75 @ResponseBody
83   - public WVPResult<PageInfo<String>> getAppList(@RequestParam int page,
  76 + public PageInfo<String> getAppList(@RequestParam int page,
84 77 @RequestParam int count){
85   - WVPResult<PageInfo<String>> result = new WVPResult<>();
86 78 List<String> resultData = new ArrayList<>();
87 79 List<File> appList = videoFileService.getAppList(true);
88 80 if (appList.size() > 0) {
... ... @@ -90,36 +82,28 @@ public class RecordController {
90 82 resultData.add(file.getName());
91 83 }
92 84 }
93   - result.setCode(0);
94   - result.setMsg("success");
95 85  
96 86 PageInfo<String> stringPageInfo = new PageInfo<>(resultData);
97 87 stringPageInfo.startPage(page, count);
98   - result.setData(stringPageInfo);
99   - return result;
  88 + return stringPageInfo;
100 89 }
101 90  
102 91 /**
103 92 * 分页stream列表
104 93 * @return
105 94 */
106   - @ApiOperation("分页stream列表")
107   - @ApiImplicitParams({
108   - @ApiImplicitParam(name="page", value = "当前页", required = true, dataTypeClass = Integer.class),
109   - @ApiImplicitParam(name="count", value = "每页查询数量", required = true, dataTypeClass = Integer.class),
110   - @ApiImplicitParam(name="app", value = "应用名", required = true, dataTypeClass = String.class),
111   - })
  95 + @Operation(summary ="分页stream列表")
  96 + @Parameter(name = "page", description = "当前页", required = true)
  97 + @Parameter(name = "count", description = "每页查询数量", required = true)
  98 + @Parameter(name = "app", description = "应用名", required = true)
112 99 @GetMapping(value = "/stream/list")
113 100 @ResponseBody
114   - public WVPResult<PageInfo<String>> getStreamList(@RequestParam int page,
  101 + public PageInfo<String> getStreamList(@RequestParam int page,
115 102 @RequestParam int count,
116 103 @RequestParam String app ){
117   - WVPResult<PageInfo<String>> result = new WVPResult<>();
118 104 List<String> resultData = new ArrayList<>();
119 105 if (app == null) {
120   - result.setCode(400);
121   - result.setMsg("app不能为空");
122   - return result;
  106 + throw new ControllerException(ErrorCode.ERROR400.getCode(), "app不能为空");
123 107 }
124 108 List<File> streamList = videoFileService.getStreamList(app, true);
125 109 if (streamList != null) {
... ... @@ -127,69 +111,54 @@ public class RecordController {
127 111 resultData.add(file.getName());
128 112 }
129 113 }
130   - result.setCode(0);
131   - result.setMsg("success");
132 114 PageInfo<String> stringPageInfo = new PageInfo<>(resultData);
133 115 stringPageInfo.startPage(page, count);
134   - result.setData(stringPageInfo);
135   - return result;
  116 + return stringPageInfo;
136 117 }
137 118  
138 119 /**
139 120 * 获取日期文件夹列表
140 121 * @return
141 122 */
142   - @ApiOperation("获取日期文件夹列表")
143   - @ApiImplicitParams({
144   - @ApiImplicitParam(name="year", value = "年", required = true, dataTypeClass = Integer.class),
145   - @ApiImplicitParam(name="month", value = "月", required = true, dataTypeClass = Integer.class),
146   - @ApiImplicitParam(name="app", value = "应用名", required = true, dataTypeClass = String.class),
147   - @ApiImplicitParam(name="stream", value = "流ID", required = true, dataTypeClass = String.class),
148   - })
  123 + @Operation(summary ="获取日期文件夹列表")
  124 + @Parameter(name = "year", description = "月", required = true)
  125 + @Parameter(name = "month", description = "年", required = true)
  126 + @Parameter(name = "app", description = "应用名", required = true)
  127 + @Parameter(name = "stream", description = "流ID", required = true)
149 128 @GetMapping(value = "/date/list")
150 129 @ResponseBody
151   - public WVPResult<List<String>> getDateList( @RequestParam(required = false) Integer year,
  130 + public List<String> getDateList( @RequestParam(required = false) Integer year,
152 131 @RequestParam(required = false) Integer month,
153 132 @RequestParam String app,
154 133 @RequestParam String stream ){
155   - WVPResult<List<String>> result = new WVPResult<>();
156 134 List<String> resultData = new ArrayList<>();
157 135 if (app == null) {
158   - result.setCode(400);
159   - result.setMsg("app不能为空");
160   - return result;
  136 + throw new ControllerException(ErrorCode.ERROR400.getCode(), "app不能为空");
161 137 };
162 138 if (stream == null) {
163   - result.setCode(400);
164   - result.setMsg("stream不能为空");
165   - return result;
  139 + throw new ControllerException(ErrorCode.ERROR400.getCode(), "stream不能为空");
166 140 }
167 141 List<File> dateList = videoFileService.getDateList(app, stream, year, month, true);
168 142 for (File file : dateList) {
169 143 resultData.add(file.getName());
170 144 }
171   - result.setCode(0);
172   - result.setMsg("success");
173   - result.setData(resultData);
174   - return result;
  145 + return resultData;
175 146 }
176 147  
177 148 /**
178 149 * 获取视频文件列表
179 150 * @return
180 151 */
181   - @ApiOperation("获取日期文件夹列表")
182   - @ApiImplicitParams({
183   - @ApiImplicitParam(name="page", value = "当前页", required = true, dataTypeClass = Integer.class),
184   - @ApiImplicitParam(name="count", value = "每页查询数量", required = true, dataTypeClass = Integer.class),
185   - @ApiImplicitParam(name="app", value = "应用名", required = true, dataTypeClass = String.class),
186   - @ApiImplicitParam(name="stream", value = "流ID", required = true, dataTypeClass = String.class),
187   - @ApiImplicitParam(name="startTime", value = "开始时间(yyyy-MM-dd HH:mm:ss)", required = false, dataTypeClass = String.class),
188   - @ApiImplicitParam(name="endTime", value = "结束时间(yyyy-MM-dd HH:mm:ss)", required = false, dataTypeClass = String.class),
189   - })
  152 + @Operation(summary ="获取日期文件夹列表")
  153 + @Parameter(name = "page", description = "当前页", required = true)
  154 + @Parameter(name = "count", description = "每页查询数量", required = true)
  155 + @Parameter(name = "app", description = "应用名", required = true)
  156 + @Parameter(name = "stream", description = "流ID", required = true)
  157 + @Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = true)
  158 + @Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = true)
190 159 @GetMapping(value = "/file/list")
191 160 @ResponseBody
192   - public WVPResult<PageInfo<String>> getRecordList(@RequestParam int page,
  161 + public PageInfo<String> getRecordList(@RequestParam int page,
193 162 @RequestParam int count,
194 163 @RequestParam String app,
195 164 @RequestParam String stream,
... ... @@ -197,7 +166,6 @@ public class RecordController {
197 166 @RequestParam(required = false) String endTime
198 167 ){
199 168  
200   - WVPResult<PageInfo<String>> result = new WVPResult<>();
201 169 // 开始时间与结束时间可不传或只传其一
202 170 List<String> recordList = new ArrayList<>();
203 171 try {
... ... @@ -216,40 +184,33 @@ public class RecordController {
216 184 recordList.add(file.getName());
217 185 }
218 186 }
219   - result.setCode(0);
220   - result.setMsg("success");
221 187 PageInfo<String> stringPageInfo = new PageInfo<>(recordList);
222 188 stringPageInfo.startPage(page, count);
223   - result.setData(stringPageInfo);
  189 + return stringPageInfo;
224 190 } catch (ParseException e) {
225 191 logger.error("错误的开始时间[{}]或结束时间[{}]", startTime, endTime);
226   - result.setCode(400);
227   - result.setMsg("错误的开始时间或结束时间");
  192 + throw new ControllerException(ErrorCode.ERROR400.getCode(), "错误的开始时间或结束时间, e=" + e.getMessage());
228 193 }
229   - return result;
230 194 }
231 195  
232 196  
233 197 /**
234 198 * 添加视频裁剪合并任务
235 199 */
236   - @ApiOperation("添加视频裁剪合并任务")
237   - @ApiImplicitParams({
238   - @ApiImplicitParam(name="app", value = "应用名", required = true, dataTypeClass = String.class),
239   - @ApiImplicitParam(name="stream", value = "流ID", required = true, dataTypeClass = String.class),
240   - @ApiImplicitParam(name="startTime", value = "开始时间(yyyy-MM-dd HH:mm:ss)", required = false, dataTypeClass = String.class),
241   - @ApiImplicitParam(name="endTime", value = "结束时间(yyyy-MM-dd HH:mm:ss)", required = false, dataTypeClass = String.class),
242   - @ApiImplicitParam(name="remoteHost", value = "服务的IP:端口(用于直接返回完整播放地址以及下载地址)", required = false, dataTypeClass = String.class),
243   - })
  200 + @Operation(summary ="添加视频裁剪合并任务")
  201 + @Parameter(name = "app", description = "应用名", required = true)
  202 + @Parameter(name = "stream", description = "流ID", required = true)
  203 + @Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = true)
  204 + @Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = true)
  205 + @Parameter(name = "remoteHost", description = "服务的IP:端口(用于直接返回完整播放地址以及下载地址)", required = true)
244 206 @GetMapping(value = "/file/download/task/add")
245 207 @ResponseBody
246   - public WVPResult<String> addTaskForDownload(@RequestParam String app,
  208 + public String addTaskForDownload(@RequestParam String app,
247 209 @RequestParam String stream,
248 210 @RequestParam(required = false) String startTime,
249 211 @RequestParam(required = false) String endTime,
250 212 @RequestParam(required = false) String remoteHost
251 213 ){
252   - WVPResult<String> result = new WVPResult<>();
253 214 Date startTimeDate = null;
254 215 Date endTimeDate = null;
255 216 try {
... ... @@ -263,111 +224,96 @@ public class RecordController {
263 224 e.printStackTrace();
264 225 }
265 226 String id = videoFileService.mergeOrCut(app, stream, startTimeDate, endTimeDate, remoteHost);
266   - result.setCode(0);
267   - result.setMsg(id!= null?"success":"error: 可能未找到视频文件");
268   - result.setData(id);
269   - return result;
  227 + if (id== null) {
  228 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "可能未找到视频文件");
  229 + }
  230 + return id;
270 231 }
271 232  
272 233 /**
273 234 * 查询视频裁剪合并任务列表
274 235 */
275   - @ApiOperation("查询视频裁剪合并任务列表")
276   - @ApiImplicitParams({
277   - @ApiImplicitParam(name="app", value = "应用名", required = false, dataTypeClass = String.class),
278   - @ApiImplicitParam(name="stream", value = "流ID", required = false, dataTypeClass = String.class),
279   - @ApiImplicitParam(name="taskId", value = "任务ID", required = false, dataTypeClass = String.class),
280   - @ApiImplicitParam(name="isEnd", value = "是否结束", required = false, dataTypeClass = Boolean.class),
281   - })
  236 + @Operation(summary ="查询视频裁剪合并任务列表")
  237 + @Parameter(name = "app", description = "应用名", required = true)
  238 + @Parameter(name = "stream", description = "流ID", required = true)
  239 + @Parameter(name = "taskId", description = "任务ID", required = true)
  240 + @Parameter(name = "isEnd", description = "是否结束", required = true)
282 241 @GetMapping(value = "/file/download/task/list")
283 242 @ResponseBody
284   - public WVPResult<List<MergeOrCutTaskInfo>> getTaskListForDownload(
  243 + public List<MergeOrCutTaskInfo> getTaskListForDownload(
285 244 @RequestParam(required = false) String app,
286 245 @RequestParam(required = false) String stream,
287 246 @RequestParam(required = false) String taskId,
288 247 @RequestParam(required = false) Boolean isEnd){
289 248 List<MergeOrCutTaskInfo> taskList = videoFileService.getTaskListForDownload(isEnd, app, stream, taskId);
290   - WVPResult<List<MergeOrCutTaskInfo>> result = new WVPResult<>();
291   - result.setCode(0);
292   - result.setMsg(taskList != null?"success":"error");
293   - result.setData(taskList);
294   - return result;
  249 + if (taskList == null) {
  250 + throw new ControllerException(ErrorCode.ERROR100);
  251 + }
  252 + return taskList;
295 253 }
296 254  
297 255 /**
298 256 * 收藏录像(被收藏的录像不会被清理任务清理)
299 257 */
300   - @ApiOperation("收藏录像(被收藏的录像不会被清理任务清理)")
301   - @ApiImplicitParams({
302   - @ApiImplicitParam(name="type", value = "类型", required = true, dataTypeClass = String.class),
303   - @ApiImplicitParam(name="app", value = "应用名", required = true, dataTypeClass = String.class),
304   - @ApiImplicitParam(name="stream", value = "流ID", required = true, dataTypeClass = String.class),
305   - })
  258 + @Operation(summary ="收藏录像(被收藏的录像不会被清理任务清理)")
  259 + @Parameter(name = "type", description = "类型", required = true)
  260 + @Parameter(name = "app", description = "应用名", required = true)
  261 + @Parameter(name = "stream", description = "流ID", required = true)
306 262 @GetMapping(value = "/file/collection/add")
307 263 @ResponseBody
308   - public WVPResult<String> collection(
  264 + public void collection(
309 265 @RequestParam(required = true) String type,
310 266 @RequestParam(required = true) String app,
311 267 @RequestParam(required = true) String stream){
312 268  
313 269 boolean collectionResult = videoFileService.collection(app, stream, type);
314   - WVPResult<String> result = new WVPResult<>();
315   - result.setCode(0);
316   - result.setMsg(collectionResult ?"success":"error");
317   - return result;
  270 + if (!collectionResult) {
  271 + throw new ControllerException(ErrorCode.ERROR100);
  272 + }
318 273 }
319 274  
320 275 /**
321 276 * 移除收藏录像
322 277 */
323   - @ApiOperation("移除收藏录像")
324   - @ApiImplicitParams({
325   - @ApiImplicitParam(name="type", value = "类型", required = true, dataTypeClass = String.class),
326   - @ApiImplicitParam(name="app", value = "应用名", required = true, dataTypeClass = String.class),
327   - @ApiImplicitParam(name="stream", value = "流ID", required = true, dataTypeClass = String.class),
328   - })
  278 + @Operation(summary ="移除收藏录像")
  279 + @Parameter(name = "type", description = "类型", required = true)
  280 + @Parameter(name = "app", description = "应用名", required = true)
  281 + @Parameter(name = "stream", description = "流ID", required = true)
329 282 @GetMapping(value = "/file/collection/remove")
330 283 @ResponseBody
331   - public WVPResult<String> removeCollection(
  284 + public void removeCollection(
332 285 @RequestParam(required = true) String type,
333 286 @RequestParam(required = true) String app,
334 287 @RequestParam(required = true) String stream){
335 288  
336 289 boolean collectionResult = videoFileService.removeCollection(app, stream, type);
337   - WVPResult<String> result = new WVPResult<>();
338   - result.setCode(0);
339   - result.setMsg(collectionResult ?"success":"error");
340   - return result;
  290 + if (!collectionResult) {
  291 + throw new ControllerException(ErrorCode.ERROR100);
  292 + }
341 293 }
342 294  
343 295 /**
344 296 * 收藏录像列表
345 297 */
346   - @ApiOperation("收藏录像列表")
347   - @ApiImplicitParams({
348   - @ApiImplicitParam(name="type", value = "类型", required = true, dataTypeClass = String.class),
349   - @ApiImplicitParam(name="app", value = "应用名", required = false, dataTypeClass = String.class),
350   - @ApiImplicitParam(name="stream", value = "流ID", required = false, dataTypeClass = String.class),
351   - })
  298 + @Operation(summary ="收藏录像列表")
  299 + @Parameter(name = "type", description = "类型", required = false)
  300 + @Parameter(name = "app", description = "应用名", required = false)
  301 + @Parameter(name = "stream", description = "流ID", required = false)
352 302 @GetMapping(value = "/file/collection/list")
353 303 @ResponseBody
354   - public WVPResult<List<SignInfo>> collectionList(
  304 + public List<SignInfo> collectionList(
355 305 @RequestParam(required = false) String type,
356 306 @RequestParam(required = false) String app,
357 307 @RequestParam(required = false) String stream){
358 308  
359 309 List<SignInfo> signInfos = videoFileService.getCollectionList(app, stream, type);
360   - WVPResult<List<SignInfo>> result = new WVPResult<>();
361   - result.setCode(0);
362   - result.setMsg(signInfos != null ?"success":"error");
363   - result.setData(signInfos);
364   - return result;
  310 + return signInfos;
365 311 }
366 312  
367 313 /**
368 314 * 中止视频裁剪合并任务列表
369 315 */
370   - @ApiOperation("中止视频裁剪合并任务列表(暂不支持)")
  316 + @Operation(summary ="中止视频裁剪合并任务列表(暂不支持)")
371 317 @GetMapping(value = "/file/download/task/stop")
372 318 @ResponseBody
373 319 public WVPResult<String> stopTaskForDownload(@RequestParam String taskId){
... ... @@ -397,7 +343,9 @@ public class RecordController {
397 343 String app = json.getString("app");
398 344 String stream = json.getString("stream");
399 345 logger.debug("ZLM 录制完成,参数:" + file_path);
400   - if (file_path == null) return new ResponseEntity<String>(ret.toString(), HttpStatus.OK);
  346 + if (file_path == null) {
  347 + return new ResponseEntity<String>(ret.toString(), HttpStatus.OK);
  348 + }
401 349 videoFileService.handFile(new File(file_path), app, stream);
402 350  
403 351 return new ResponseEntity<String>(ret.toString(), HttpStatus.OK);
... ... @@ -406,54 +354,39 @@ public class RecordController {
406 354 /**
407 355 * 磁盘空间查询
408 356 */
409   - @ApiOperation("磁盘空间查询")
  357 + @Operation(summary ="磁盘空间查询")
410 358 @ResponseBody
411 359 @GetMapping(value = "/space", produces = "application/json;charset=UTF-8")
412   - public ResponseEntity<String> getSpace() {
413   - JSONObject ret = new JSONObject();
414   - ret.put("code", 0);
415   - ret.put("msg", "success");
416   - SpaceInfo spaceInfo = videoFileService.getSpaceInfo();
417   - ret.put("data", JSON.toJSON(spaceInfo));
418   - return new ResponseEntity<>(ret.toString(), HttpStatus.OK);
419   - }
420   -
421   - /**
422   - * 录像文件的时长
423   - */
424   - @ApiOperation("录像文件的时长")
425   - @ApiImplicitParams({
426   - @ApiImplicitParam(name="app", value = "应用名", required = true, dataTypeClass = String.class),
427   - @ApiImplicitParam(name="stream", value = "流ID", required = true, dataTypeClass = String.class),
428   - @ApiImplicitParam(name="recordIng", value = "是否录制中", required = false, dataTypeClass = String.class),
429   - })
430   - @ResponseBody
431   - @GetMapping(value = "/file/duration", produces = "application/json;charset=UTF-8")
432   - @PostMapping(value = "/file/duration", produces = "application/json;charset=UTF-8")
433   - public ResponseEntity<String> fileDuration( @RequestParam String app, @RequestParam String stream) {
434   - JSONObject ret = new JSONObject();
435   - ret.put("code", 0);
436   - ret.put("msg", "success");
437   - long duration = videoFileService.fileDuration(app, stream);
438   - ret.put("data", duration);
439   - return new ResponseEntity<>(ret.toString(), HttpStatus.OK);
  360 + public SpaceInfo getSpace() {
  361 + return videoFileService.getSpaceInfo();
440 362 }
441 363  
442 364 /**
443 365 * 增加推流的鉴权信息,用于录像存储使用
444 366 */
445   - @ApiOperation("增加推流的鉴权信息")
446   - @ApiImplicitParams({
447   - @ApiImplicitParam(name="app", value = "应用名", required = true, dataTypeClass = String.class),
448   - @ApiImplicitParam(name="stream", value = "流ID", required = true, dataTypeClass = String.class),
449   - @ApiImplicitParam(name="callId", value = "录像自鉴权ID", required = true, dataTypeClass = String.class),
450   - })
  367 + @Operation(summary ="增加推流的鉴权信息")
  368 + @Parameter(name = "app", description = "应用名", required = true)
  369 + @Parameter(name = "stream", description = "流ID", required = true)
  370 + @Parameter(name = "callId", description = "录像自鉴权ID", required = true)
451 371 @ResponseBody
452 372 @GetMapping(value = "/addStreamCallInfo", produces = "application/json;charset=UTF-8")
453 373 @PostMapping(value = "/addStreamCallInfo", produces = "application/json;charset=UTF-8")
454   - public ResponseEntity<String> addStreamCallInfo(String app, String stream, String callId) {
  374 + public void addStreamCallInfo(String app, String stream, String callId) {
455 375 String key = "Stream_Call_Info" + app + "_" + stream;
456 376 redisUtil.set(key, callId, -1);
457   - return new ResponseEntity<>(null, HttpStatus.OK);
  377 + }
  378 +
  379 + /**
  380 + * 录像文件的时长
  381 + */
  382 + @Operation(summary ="录像文件的时长")
  383 + @Parameter(name = "app", description = "应用名", required = true)
  384 + @Parameter(name = "stream", description = "流ID", required = true)
  385 + @Parameter(name = "recordIng", description = "是否录制中", required = true)
  386 + @ResponseBody
  387 + @GetMapping(value = "/file/duration", produces = "application/json;charset=UTF-8")
  388 + @PostMapping(value = "/file/duration", produces = "application/json;charset=UTF-8")
  389 + public long fileDuration( @RequestParam String app, @RequestParam String stream) {
  390 + return videoFileService.fileDuration(app, stream);
458 391 }
459 392 }
... ...
src/main/java/top/panll/assist/controller/bean/ControllerException.java 0 → 100644
  1 +package top.panll.assist.controller.bean;
  2 +
  3 +/**
  4 + * 自定义异常,controller出现错误时直接抛出异常由全局异常捕获并返回结果
  5 + */
  6 +public class ControllerException extends RuntimeException{
  7 +
  8 + private int code;
  9 + private String msg;
  10 +
  11 + public ControllerException(int code, String msg) {
  12 + this.code = code;
  13 + this.msg = msg;
  14 + }
  15 + public ControllerException(ErrorCode errorCode) {
  16 + this.code = errorCode.getCode();
  17 + this.msg = errorCode.getMsg();
  18 + }
  19 +
  20 + public int getCode() {
  21 + return code;
  22 + }
  23 +
  24 + public void setCode(int code) {
  25 + this.code = code;
  26 + }
  27 +
  28 + public String getMsg() {
  29 + return msg;
  30 + }
  31 +
  32 + public void setMsg(String msg) {
  33 + this.msg = msg;
  34 + }
  35 +}
... ...
src/main/java/top/panll/assist/controller/bean/ErrorCode.java 0 → 100644
  1 +package top.panll.assist.controller.bean;
  2 +
  3 +/**
  4 + * 全局错误码
  5 + */
  6 +public enum ErrorCode {
  7 + SUCCESS(0, "成功"),
  8 + ERROR100(100, "失败"),
  9 + ERROR400(400, "参数不全或者错误"),
  10 + ERROR403(403, "无权限操作"),
  11 + ERROR401(401, "请登录后重新请求"),
  12 + ERROR500(500, "系统异常");
  13 +
  14 + private final int code;
  15 + private final String msg;
  16 +
  17 + ErrorCode(int code, String msg) {
  18 + this.code = code;
  19 + this.msg = msg;
  20 + }
  21 +
  22 + public int getCode() {
  23 + return code;
  24 + }
  25 +
  26 + public String getMsg() {
  27 + return msg;
  28 + }
  29 +}
... ...
src/main/java/top/panll/assist/controller/bean/WVPResult.java
1 1 package top.panll.assist.controller.bean;
2 2  
  3 +
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +
  6 +@Schema(description = "统一返回结果")
3 7 public class WVPResult<T> {
4 8  
  9 + public WVPResult() {
  10 + }
  11 +
  12 + public WVPResult(int code, String msg, T data) {
  13 + this.code = code;
  14 + this.msg = msg;
  15 + this.data = data;
  16 + }
  17 +
  18 +
  19 + @Schema(description = "错误码,0为成功")
5 20 private int code;
  21 + @Schema(description = "描述,错误时描述错误原因")
6 22 private String msg;
  23 + @Schema(description = "数据")
7 24 private T data;
8 25  
  26 +
  27 + public static <T> WVPResult<T> success(T t, String msg) {
  28 + return new WVPResult<>(ErrorCode.SUCCESS.getCode(), msg, t);
  29 + }
  30 +
  31 + public static <T> WVPResult<T> success(T t) {
  32 + return success(t, ErrorCode.SUCCESS.getMsg());
  33 + }
  34 +
  35 + public static <T> WVPResult<T> fail(int code, String msg) {
  36 + return new WVPResult<>(code, msg, null);
  37 + }
  38 +
  39 + public static <T> WVPResult<T> fail(ErrorCode errorCode) {
  40 + return fail(errorCode.getCode(), errorCode.getMsg());
  41 + }
  42 +
9 43 public int getCode() {
10 44 return code;
11 45 }
... ...
src/main/java/top/panll/assist/service/VideoFileService.java
... ... @@ -518,7 +518,6 @@ public class VideoFileService {
518 518 }else {
519 519 result.add((MergeOrCutTaskInfo)redisUtil.get(keyItem));
520 520 }
521   -
522 521 }
523 522 }
524 523 result.sort((MergeOrCutTaskInfo m1, MergeOrCutTaskInfo m2)->{
... ...
src/main/java/top/panll/assist/utils/RedisUtil.java
... ... @@ -707,28 +707,18 @@ public class RedisUtil {
707 707 * @return
708 708 */
709 709 public List<Object> scan(String query) {
710   - Set<String> keys = (Set<String>) redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
711   - Set<String> keysTmp = new HashSet<>();
712   - Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(query).count(1000).build());
713   - while (cursor.hasNext()) {
714   - keysTmp.add(new String(cursor.next()));
  710 + Set<String> resultKeys = redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
  711 + ScanOptions scanOptions = ScanOptions.scanOptions().match("*" + query + "*").count(1000).build();
  712 + Cursor<byte[]> scan = connection.scan(scanOptions);
  713 + Set<String> keys = new HashSet<>();
  714 + while (scan.hasNext()) {
  715 + byte[] next = scan.next();
  716 + keys.add(new String(next));
715 717 }
716   - return keysTmp;
  718 + return keys;
717 719 });
718   -// Set<String> keys = (Set<String>) redisTemplate.execute(new RedisCallback<Set<String>>(){
719   -//
720   -// @Override
721   -// public Set<String> doInRedis(RedisConnection connection) throws DataAccessException {
722   -// Set<String> keysTmp = new HashSet<>();
723   -// Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(query).count(1000).build());
724   -// while (cursor.hasNext()) {
725   -// keysTmp.add(new String(cursor.next()));
726   -// }
727   -// return keysTmp;
728   -// }
729   -// });
730 720  
731   - return new ArrayList<>(keys);
  721 + return new ArrayList<>(resultKeys);
732 722 }
733 723  
734 724 public void convertAndSend(String channel, Object msg) {
... ...
src/main/resources/application-dev.yml
... ... @@ -42,7 +42,7 @@ userSettings:
42 42 threads: 2
43 43  
44 44 swagger-ui:
45   - enabled: true
  45 +
46 46 # [可选] 日志配置, 一般不需要改
47 47 logging:
48 48 file:
... ...
src/main/resources/application-local.yml 0 → 100644
  1 +spring:
  2 + # REDIS数据库配置
  3 + redis:
  4 + # [可选] 超时时间
  5 + timeout: 10000
  6 + # 以下为单机配置
  7 + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
  8 + host: 127.0.0.1
  9 + # [必须修改] 端口号
  10 + port: 6379
  11 + # [可选] 数据库 DB
  12 + database: 1
  13 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
  14 + password: adminadmin123.
  15 + # 以下为集群配置
  16 +# cluster:
  17 +# nodes: 192.168.1.242:7001
  18 +# password: 4767cb971b40a1300fa09b7f87b09d1c
  19 +
  20 +# [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
  21 +server:
  22 + port: 18089
  23 + # [可选] HTTPS配置, 默认不开启
  24 + ssl:
  25 + # [可选] 是否开启HTTPS访问
  26 + enabled: false
  27 + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名
  28 + key-store: classpath:xxx.jks
  29 + # [可选] 证书密码
  30 + key-password: password
  31 + # [可选] 证书类型, 默认为jks,根据实际修改
  32 + key-store-type: JKS
  33 +
  34 +# [根据业务需求配置]
  35 +userSettings:
  36 + # [必选 ] zlm配置的录像路径
  37 + record: /home/lin/server/test001/default/www/record/
  38 + # [可选 ] 录像保存时长(单位: 天)每天晚12点自动对过期文件执行清理
  39 + recordDay: 7
  40 + # [可选 ] 录像下载合成临时文件保存时长, 不配置默认取值recordDay(单位: 天)每天晚12点自动对过期文件执行清理
  41 + # recordTempDay: 7
  42 + # [必选 ] ffmpeg路径
  43 + ffmpeg: /home/lin/IdeaProjects/wvp-pro-assist/lib/ffmpeg
  44 + # [必选 ] ffprobe路径, 一般安装ffmpeg就会自带, 一般跟ffmpeg在同一目录,用于查询文件的信息
  45 + ffprobe: /home/lin/IdeaProjects/wvp-pro-assist/lib/ffprobe
  46 + # [可选 ] 限制 ffmpeg 合并文件使用的线程数,间接限制cpu使用率, 默认2 限制到50%
  47 + threads: 2
  48 +
  49 +swagger-ui:
  50 +
  51 +# [可选] 日志配置, 一般不需要改
  52 +logging:
  53 + file:
  54 + name: logs/wvp.log
  55 + max-history: 30
  56 + max-size: 10MB
  57 + total-size-cap: 300MB
  58 + level:
  59 + root: WARN
  60 + top:
  61 + panll:
  62 + assist: info
0 63 \ No newline at end of file
... ...
src/main/resources/application.yml
1 1 spring:
2 2 profiles:
3   - active: dev
  3 + active: local
... ...