Merge branch 'master' of ssh://gitea.ttstd.com:2222/tt/youlai-boot
This commit is contained in:
@@ -22,7 +22,7 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
*/
|
*/
|
||||||
@Tag(name = "01.认证中心")
|
@Tag(name = "01.认证中心")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/auth/app")
|
@RequestMapping("/api/v1/app/auth/")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AppAuthController {
|
public class AppAuthController {
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.youlai.boot.app.controller;
|
||||||
|
|
||||||
|
import com.youlai.boot.app.model.vo.AppFileInfo;
|
||||||
|
import com.youlai.boot.app.service.AppFileService;
|
||||||
|
import com.youlai.boot.common.result.Result;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件控制层
|
||||||
|
*
|
||||||
|
* @author Ray.Hao
|
||||||
|
* @since 2022/10/16
|
||||||
|
*/
|
||||||
|
@Tag(name = "10.文件接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/app/files")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AppFileController {
|
||||||
|
|
||||||
|
private final AppFileService fileService;
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@Operation(summary = "文件上传")
|
||||||
|
public Result<AppFileInfo> uploadFile(
|
||||||
|
@Parameter(
|
||||||
|
name = "file",
|
||||||
|
description = "表单文件对象",
|
||||||
|
required = true,
|
||||||
|
in = ParameterIn.DEFAULT,
|
||||||
|
schema = @Schema(name = "file", format = "binary")
|
||||||
|
)
|
||||||
|
@RequestPart(value = "file") MultipartFile file
|
||||||
|
) {
|
||||||
|
Assert.isTrue(!file.isEmpty(), "上传文件不能为空文件");
|
||||||
|
AppFileInfo fileInfo = fileService.uploadFile(file);
|
||||||
|
return Result.success(fileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping
|
||||||
|
@Operation(summary = "文件删除")
|
||||||
|
@SneakyThrows
|
||||||
|
public Result<?> deleteFile(
|
||||||
|
@Parameter(description = "文件路径") @RequestParam String filePath
|
||||||
|
) {
|
||||||
|
boolean result = fileService.deleteFile(filePath);
|
||||||
|
return Result.judge(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/main/java/com/youlai/boot/app/model/vo/AppFileInfo.java
Normal file
23
src/main/java/com/youlai/boot/app/model/vo/AppFileInfo.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package com.youlai.boot.app.model.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件信息对象
|
||||||
|
*
|
||||||
|
* @author Ray.Hao
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Schema(description = "文件对象")
|
||||||
|
@Data
|
||||||
|
public class AppFileInfo {
|
||||||
|
|
||||||
|
@Schema(description = "文件名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "文件URL")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.youlai.boot.app.service;
|
||||||
|
|
||||||
|
import com.youlai.boot.app.model.vo.AppFileInfo;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象存储服务接口层
|
||||||
|
*
|
||||||
|
* @author haoxr
|
||||||
|
* @since 2022/11/19
|
||||||
|
*/
|
||||||
|
public interface AppFileService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
* @param file 表单文件对象
|
||||||
|
* @return 文件信息
|
||||||
|
*/
|
||||||
|
AppFileInfo uploadFile(MultipartFile file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文件
|
||||||
|
*
|
||||||
|
* @param filePath 文件完整URL
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
|
boolean deleteFile(String filePath);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package com.youlai.boot.app.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DatePattern;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import com.youlai.boot.app.model.vo.AppFileInfo;
|
||||||
|
import com.youlai.boot.app.service.AppFileService;
|
||||||
|
import com.youlai.boot.file.service.FileService;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地存储服务类
|
||||||
|
*
|
||||||
|
* @author Theo
|
||||||
|
* @since 2024-12-09 17:11
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
//@ConditionalOnProperty(value = "oss.type", havingValue = "local")
|
||||||
|
//@ConfigurationProperties(prefix = "oss.local")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class LocalAppFileService implements AppFileService {
|
||||||
|
|
||||||
|
@Value("${oss.local.storage-path}")
|
||||||
|
private String storagePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件方法
|
||||||
|
*
|
||||||
|
* @param file 表单文件对象
|
||||||
|
* @return 文件信息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AppFileInfo uploadFile(MultipartFile file) {
|
||||||
|
// 获取文件名
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
// 获取文件后缀
|
||||||
|
String suffix = FileUtil.getSuffix(originalFilename);
|
||||||
|
// 生成uuid
|
||||||
|
String fileName = IdUtil.simpleUUID()+ "." + suffix;;
|
||||||
|
// 生成文件名(日期文件夹)
|
||||||
|
String folder = DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATE_PATTERN);
|
||||||
|
String filePrefix = storagePath.endsWith(File.separator) ? storagePath : storagePath + File.separator;
|
||||||
|
// try-with-resource 语法糖自动释放流
|
||||||
|
try (InputStream inputStream = file.getInputStream()) {
|
||||||
|
// 上传文件
|
||||||
|
FileUtil.writeFromStream(inputStream, filePrefix + folder + File.separator + fileName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("文件上传失败", e);
|
||||||
|
throw new RuntimeException("文件上传失败");
|
||||||
|
}
|
||||||
|
// 获取文件访问路径,因为这里是本地存储,所以直接返回文件的相对路径,需要前端自行处理访问前缀
|
||||||
|
String fileUrl = File.separator + folder + File.separator + fileName;
|
||||||
|
AppFileInfo fileInfo = new AppFileInfo();
|
||||||
|
fileInfo.setName(originalFilename);
|
||||||
|
fileInfo.setUrl(fileUrl);
|
||||||
|
return fileInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文件
|
||||||
|
* @param filePath 文件完整URL
|
||||||
|
* @return 是否删除成功
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean deleteFile(String filePath) {
|
||||||
|
//判断文件是否为空
|
||||||
|
if (filePath == null || filePath.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 判断filepath是否为文件夹
|
||||||
|
if (FileUtil.isDirectory(storagePath + filePath)) {
|
||||||
|
// 禁止删除文件夹
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 删除文件
|
||||||
|
return FileUtil.del(storagePath + filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -71,7 +71,7 @@ public class SecurityConfig {
|
|||||||
|
|
||||||
// 移动设备专用接口路径(需要设备签名验证,但不需要用户登录)
|
// 移动设备专用接口路径(需要设备签名验证,但不需要用户登录)
|
||||||
requestMatcherRegistry.requestMatchers("/api/v1/sn/**").permitAll();
|
requestMatcherRegistry.requestMatchers("/api/v1/sn/**").permitAll();
|
||||||
requestMatcherRegistry.requestMatchers("/api/v1/auth/app/**").permitAll();
|
requestMatcherRegistry.requestMatchers("/api/v1/app/**").permitAll();
|
||||||
// 其他所有请求需登录后访问
|
// 其他所有请求需登录后访问
|
||||||
requestMatcherRegistry.anyRequest().authenticated();
|
requestMatcherRegistry.anyRequest().authenticated();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user