增加文件中心与客户端功能,增加文件远程上传与下载功能
This commit is contained in:
parent
4354516b20
commit
f7468f77fd
@ -1,10 +1,8 @@
|
||||
package ink.wgink.module.file.components;
|
||||
|
||||
import ink.wgink.exceptions.FileException;
|
||||
import ink.wgink.exceptions.SearchException;
|
||||
import ink.wgink.exceptions.base.SystemException;
|
||||
import ink.wgink.module.file.enums.UploadTypeEnum;
|
||||
import ink.wgink.module.file.service.IFileService;
|
||||
import ink.wgink.properties.FileProperties;
|
||||
import ink.wgink.util.date.DateUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -14,12 +12,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* @ClassName: FileUtil
|
||||
@ -32,106 +24,13 @@ import java.security.NoSuchAlgorithmException;
|
||||
public class FileComponent {
|
||||
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(FileComponent.class);
|
||||
private static final char[] HEX_CODE = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
private String[] imageTypes;
|
||||
private String[] videoTypes;
|
||||
private String[] audioTypes;
|
||||
private String[] fileTypes;
|
||||
private String[] imageTypes = null;
|
||||
private String[] videoTypes = null;
|
||||
private String[] audioTypes = null;
|
||||
private String[] fileTypes = null;
|
||||
@Autowired
|
||||
private FileProperties fileProperties;
|
||||
|
||||
/**
|
||||
* 保存文件
|
||||
*
|
||||
* @param fileInputStream
|
||||
* @param fileName
|
||||
* @param filePath
|
||||
* @return
|
||||
*/
|
||||
public long saveFile(InputStream fileInputStream, String fileName, String filePath) {
|
||||
File uploadFolder = new File(filePath);
|
||||
if (!uploadFolder.exists()) {
|
||||
uploadFolder.mkdirs();
|
||||
}
|
||||
FileOutputStream uploadFileOutputStream = null;
|
||||
long fileSize = 0;
|
||||
try {
|
||||
uploadFileOutputStream = new FileOutputStream(uploadFolder + File.separator + fileName);
|
||||
int readLength;
|
||||
for (byte[] buf = new byte[IFileService.INPUT_STREAM_SIZE]; (readLength = fileInputStream.read(buf)) > -1; ) {
|
||||
uploadFileOutputStream.write(buf, 0, readLength);
|
||||
fileSize += readLength;
|
||||
}
|
||||
uploadFileOutputStream.flush();
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
throw new FileException("文件上传失败");
|
||||
} finally {
|
||||
try {
|
||||
if (null != uploadFileOutputStream) {
|
||||
uploadFileOutputStream.close();
|
||||
}
|
||||
if (null != fileInputStream) {
|
||||
fileInputStream.close();
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
LOG.error(e1.getMessage());
|
||||
throw new FileException("文件上传失败");
|
||||
}
|
||||
}
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除源文件
|
||||
*
|
||||
* @param sourceFilePath
|
||||
*/
|
||||
public static void deleteSourceFile(String sourceFilePath) {
|
||||
File file = new File(sourceFilePath);
|
||||
if (file.exists()) {
|
||||
boolean isDelete = file.delete();
|
||||
if (isDelete) {
|
||||
LOG.debug("文件删除成功");
|
||||
} else {
|
||||
LOG.debug("文件删除失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件的MD5
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
public String getFileMD5(File file) {
|
||||
if (file == null) {
|
||||
throw new SearchException("文件不存在");
|
||||
}
|
||||
if (!file.exists()) {
|
||||
throw new SearchException("文件不存在");
|
||||
}
|
||||
String fileMd5;
|
||||
try (InputStream inputStream = Files.newInputStream(file.toPath())) {
|
||||
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
|
||||
int readLength;
|
||||
for (byte[] buf = new byte[IFileService.INPUT_STREAM_SIZE]; (readLength = inputStream.read(buf)) > -1; ) {
|
||||
messageDigest.update(buf, 0, readLength);
|
||||
}
|
||||
// 计算文件的MD5
|
||||
byte[] data = messageDigest.digest();
|
||||
StringBuilder fileMd5SB = new StringBuilder(data.length * 2);
|
||||
for (byte b : data) {
|
||||
fileMd5SB.append(HEX_CODE[(b >> 4) & 0xF]);
|
||||
fileMd5SB.append(HEX_CODE[(b & 0xF)]);
|
||||
}
|
||||
fileMd5 = fileMd5SB.toString();
|
||||
} catch (IOException | NoSuchAlgorithmException e) {
|
||||
throw new SystemException(e);
|
||||
}
|
||||
return fileMd5;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传绝对文件
|
||||
|
@ -0,0 +1,104 @@
|
||||
package ink.wgink.module.file.controller.api.fileclient;
|
||||
|
||||
import ink.wgink.annotation.CheckRequestBodyAnnotation;
|
||||
import ink.wgink.common.base.DefaultBaseController;
|
||||
import ink.wgink.exceptions.RemoveException;
|
||||
import ink.wgink.exceptions.SearchException;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.file.pojo.dtos.fileclient.FileClientDTO;
|
||||
import ink.wgink.module.file.pojo.vos.fileremote.FileClientVO;
|
||||
import ink.wgink.module.file.service.fileclient.IFileClientService;
|
||||
import ink.wgink.pojo.ListPage;
|
||||
import ink.wgink.pojo.result.ErrorResult;
|
||||
import ink.wgink.pojo.result.SuccessResult;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName: FileClientController
|
||||
* @Description: 文件远程
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/4 22:18
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "文件客户端接口")
|
||||
@RestController
|
||||
@RequestMapping(ISystemConstant.API_PREFIX + "/file-client")
|
||||
public class FileClientController extends DefaultBaseController {
|
||||
|
||||
@Autowired
|
||||
private IFileClientService fileRemoteService;
|
||||
|
||||
@ApiOperation(value = "新增", notes = "新增接口")
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PostMapping("save")
|
||||
@CheckRequestBodyAnnotation
|
||||
public SuccessResult save(@RequestBody FileClientVO fileClientVO) {
|
||||
fileRemoteService.save(fileClientVO);
|
||||
return new SuccessResult();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "删除(id列表)", notes = "删除(id列表)接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "ids", value = "ID列表,用下划线分隔", paramType = "path", example = "1_2_3")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@DeleteMapping("remove/{ids}")
|
||||
public SuccessResult remove(@PathVariable("ids") String ids) throws RemoveException {
|
||||
fileRemoteService.remove(Arrays.asList(ids.split("\\_")));
|
||||
return new SuccessResult();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "修改", notes = "修改接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "fileClientId", value = "主键", paramType = "path")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PutMapping("update/{fileClientId}")
|
||||
@CheckRequestBodyAnnotation
|
||||
public SuccessResult update(@PathVariable("fileClientId") String fileClientId, @RequestBody FileClientVO fileClientVO) {
|
||||
fileRemoteService.update(fileClientId, fileClientVO);
|
||||
return new SuccessResult();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "详情(通过ID)", notes = "详情(通过ID)接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "fileClientId", value = "主键", paramType = "path")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("get/{fileClientId}")
|
||||
public FileClientDTO get(@PathVariable("fileClientId") String fileClientId) {
|
||||
return fileRemoteService.get(fileClientId);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "列表", notes = "列表接口")
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("list")
|
||||
public List<FileClientDTO> list() throws SearchException {
|
||||
Map<String, Object> params = requestParams();
|
||||
return fileRemoteService.list(params);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "分页列表", notes = "分页列表接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "int", defaultValue = "1"),
|
||||
@ApiImplicitParam(name = "rows", value = "显示数量", paramType = "query", dataType = "int", defaultValue = "20"),
|
||||
@ApiImplicitParam(name = "keywords", value = "关键字", paramType = "query", dataType = "String"),
|
||||
@ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"),
|
||||
@ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "String")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@GetMapping("listpage")
|
||||
public SuccessResultList<List<FileClientDTO>> listPage(ListPage page) throws SearchException {
|
||||
Map<String, Object> params = requestParams();
|
||||
page.setParams(params);
|
||||
return fileRemoteService.listPage(page);
|
||||
}
|
||||
|
||||
}
|
@ -13,9 +13,18 @@ import ink.wgink.pojo.result.SuccessResultData;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -45,6 +54,66 @@ public class FileController extends DefaultBaseController {
|
||||
return uploadSingle(file, UploadTypeEnum.FILE);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "上传文件", notes = "上传文件接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "file", value = "文件name", paramType = "query")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PostMapping("upload-file-inputstream")
|
||||
public SuccessResultData<FileUploadSuccessDTO> uploadFileInputStream(@RequestParam("file") MultipartFile file) throws IOException {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
String url = "http://localhost:7008/study/api/file/v2/upload-file";
|
||||
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
|
||||
InputStreamResource inputStreamResource = new InputStreamResource(file.getInputStream()) {
|
||||
@Override
|
||||
public String getFilename() {
|
||||
return file.getOriginalFilename();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long contentLength() {
|
||||
return file.getSize();
|
||||
}
|
||||
};
|
||||
params.add("file", inputStreamResource);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
|
||||
String result = restTemplate.postForObject(url, requestEntity, String.class);
|
||||
System.out.println(result);
|
||||
return new SuccessResultData<>();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "上传文件", notes = "上传文件接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "file", value = "文件name", paramType = "query")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PostMapping("upload-file-bytearray")
|
||||
public SuccessResultData<FileUploadSuccessDTO> uploadFileByteArray(@RequestParam("file") MultipartFile file) throws IOException {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
String url = "http://localhost:7008/study/api/file/v2/upload-file";
|
||||
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
|
||||
ByteArrayResource fileAsResource = new ByteArrayResource(file.getBytes()) {
|
||||
@Override
|
||||
public String getFilename() {
|
||||
return file.getOriginalFilename();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long contentLength() {
|
||||
return file.getSize();
|
||||
}
|
||||
};
|
||||
params.add("file", fileAsResource);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
|
||||
String result = restTemplate.postForObject(url, requestEntity, String.class);
|
||||
System.out.println(result);
|
||||
return new SuccessResultData<>();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "上传图片", notes = "上传图片接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "image", value = "文件name", paramType = "query")
|
||||
|
@ -0,0 +1,114 @@
|
||||
package ink.wgink.module.file.controller.app.api.filecenter;
|
||||
|
||||
import ink.wgink.common.base.DefaultBaseController;
|
||||
import ink.wgink.exceptions.ParamsException;
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import ink.wgink.module.file.enums.UploadTypeEnum;
|
||||
import ink.wgink.module.file.manager.FileRemoteManager;
|
||||
import ink.wgink.module.file.pojo.dtos.v2.FileUploadSuccessDTO;
|
||||
import ink.wgink.module.file.service.filecenter.IFileCenterService;
|
||||
import ink.wgink.pojo.result.ErrorResult;
|
||||
import ink.wgink.pojo.result.SuccessResultData;
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* @ClassName: FileAppCenterController
|
||||
* @Description: APP文件远程
|
||||
* @Author: WangGeng
|
||||
* @Date: 2019-08-02 15:38
|
||||
* @Version: 1.0
|
||||
**/
|
||||
@Api(tags = ISystemConstant.API_TAGS_APP_PREFIX + "文件远程调用接口")
|
||||
@RestController("fileAppCenterControllerV2")
|
||||
@RequestMapping(ISystemConstant.APP_PREFIX + "/file-center")
|
||||
public class FileCenterAppController extends DefaultBaseController {
|
||||
|
||||
@Autowired
|
||||
private IFileCenterService fileCenterService;
|
||||
|
||||
@ApiOperation(value = "上传文件", notes = "上传文件接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "Access-Key", value = "Access-Key", paramType = "header"),
|
||||
@ApiImplicitParam(name = "Access-Secret", value = "Access-Secret", paramType = "header"),
|
||||
@ApiImplicitParam(name = "file", value = "文件", paramType = "form"),
|
||||
@ApiImplicitParam(name = "creator", value = "创建人", paramType = "form")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PostMapping("upload-file")
|
||||
public SuccessResultData<FileUploadSuccessDTO> uploadFile(@RequestHeader("Access-Key") String accessKey,
|
||||
@RequestHeader("Access-Secret") String accessSecret,
|
||||
@RequestParam("file") MultipartFile file,
|
||||
@RequestParam("creator") String creator) {
|
||||
checkKeyAndSecret(accessKey, accessSecret);
|
||||
return new SuccessResultData<>(fileCenterService.uploadSingleByUserId(creator, file, UploadTypeEnum.FILE));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "上传图片", notes = "上传图片接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "Access-Key", value = "Access-Key", paramType = "header"),
|
||||
@ApiImplicitParam(name = "Access-Secret", value = "Access-Secret", paramType = "header"),
|
||||
@ApiImplicitParam(name = "image", value = "图片", paramType = "form"),
|
||||
@ApiImplicitParam(name = "creator", value = "创建人", paramType = "form")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PostMapping("upload-image")
|
||||
public SuccessResultData<FileUploadSuccessDTO> uploadImage(@RequestHeader("Access-Key") String accessKey,
|
||||
@RequestHeader("Access-Secret") String accessSecret,
|
||||
@RequestParam("image") MultipartFile image,
|
||||
@RequestParam("creator") String creator) {
|
||||
checkKeyAndSecret(accessKey, accessSecret);
|
||||
return new SuccessResultData<>(fileCenterService.uploadSingleByUserId(creator, image, UploadTypeEnum.IMAGE));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "上传视频", notes = "上传视频接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "Access-Key", value = "Access-Key", paramType = "header"),
|
||||
@ApiImplicitParam(name = "Access-Secret", value = "Access-Secret", paramType = "header"),
|
||||
@ApiImplicitParam(name = "video", value = "视频", paramType = "form"),
|
||||
@ApiImplicitParam(name = "creator", value = "创建人", paramType = "form")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PostMapping("upload-video")
|
||||
public SuccessResultData<FileUploadSuccessDTO> uploadVideo(@RequestHeader("Access-Key") String accessKey,
|
||||
@RequestHeader("Access-Secret") String accessSecret,
|
||||
@RequestParam("video") MultipartFile video,
|
||||
@RequestParam("creator") String creator) {
|
||||
checkKeyAndSecret(accessKey, accessSecret);
|
||||
return new SuccessResultData<>(fileCenterService.uploadSingleByUserId(creator, video, UploadTypeEnum.VIDEO));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "上传音频", notes = "上传音频接口")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "Access-Key", value = "Access-Key", paramType = "header"),
|
||||
@ApiImplicitParam(name = "Access-Secret", value = "Access-Secret", paramType = "header"),
|
||||
@ApiImplicitParam(name = "audio", value = "音频", paramType = "form"),
|
||||
@ApiImplicitParam(name = "creator", value = "创建人", paramType = "form")
|
||||
})
|
||||
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
|
||||
@PostMapping("upload-audio")
|
||||
public SuccessResultData<FileUploadSuccessDTO> uploadAudio(@RequestHeader("Access-Key") String accessKey,
|
||||
@RequestHeader("Access-Secret") String accessSecret,
|
||||
@RequestParam("audio") MultipartFile audio,
|
||||
@RequestParam("creator") String creator) {
|
||||
checkKeyAndSecret(accessKey, accessSecret);
|
||||
return new SuccessResultData<>(fileCenterService.uploadSingleByUserId(creator, audio, UploadTypeEnum.AUDIO));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 校验Key与Secret
|
||||
*
|
||||
* @param accessKey
|
||||
* @param accessSecret
|
||||
*/
|
||||
private void checkKeyAndSecret(String accessKey, String accessSecret) {
|
||||
if (!FileRemoteManager.getInstance().check(accessKey, accessSecret)) {
|
||||
throw new ParamsException("Key与Secret不匹配");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package ink.wgink.module.file.controller.route.fileclient;
|
||||
|
||||
import ink.wgink.interfaces.consts.ISystemConstant;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
* @ClassName: FileRemoteRouteController
|
||||
* @Description: 文件远程
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/4 22:23
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "文件远程")
|
||||
@Controller
|
||||
@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/file-client")
|
||||
public class FileClientRouteController {
|
||||
|
||||
@GetMapping("list")
|
||||
public ModelAndView list() {
|
||||
ModelAndView modelAndView = new ModelAndView("file-client/list");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@GetMapping("save")
|
||||
public ModelAndView save() {
|
||||
ModelAndView modelAndView = new ModelAndView("file-client/save");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@GetMapping("update")
|
||||
public ModelAndView update() {
|
||||
ModelAndView modelAndView = new ModelAndView("file-client/update");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package ink.wgink.module.file.dao.fileclient;
|
||||
|
||||
import ink.wgink.exceptions.RemoveException;
|
||||
import ink.wgink.exceptions.SaveException;
|
||||
import ink.wgink.exceptions.SearchException;
|
||||
import ink.wgink.exceptions.UpdateException;
|
||||
import ink.wgink.interfaces.init.IInitBaseTable;
|
||||
import ink.wgink.module.file.pojo.dtos.fileclient.FileClientDTO;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName: IFileRemoteDao
|
||||
* @Description: 文件远程
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/4 20:53
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Repository
|
||||
public interface IFileClientDao extends IInitBaseTable {
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*
|
||||
* @param params
|
||||
* @throws SaveException
|
||||
*/
|
||||
void save(Map<String, Object> params) throws SaveException;
|
||||
|
||||
/**
|
||||
* @param params
|
||||
* @throws RemoveException
|
||||
*/
|
||||
void remove(Map<String, Object> params) throws RemoveException;
|
||||
|
||||
|
||||
/**
|
||||
* 修改状态
|
||||
*
|
||||
* @param params
|
||||
* @throws UpdateException
|
||||
*/
|
||||
void update(Map<String, Object> params) throws UpdateException;
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*
|
||||
* @param params
|
||||
* @return
|
||||
* @throws SearchException
|
||||
*/
|
||||
FileClientDTO get(Map<String, Object> params) throws SearchException;
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @param params
|
||||
* @return
|
||||
* @throws SearchException
|
||||
*/
|
||||
List<FileClientDTO> list(Map<String, Object> params) throws SearchException;
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package ink.wgink.module.file.manager;
|
||||
|
||||
import ink.wgink.module.file.dao.fileclient.IFileClientDao;
|
||||
import ink.wgink.module.file.pojo.dtos.fileclient.FileClientDTO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @ClassName: FileRemoteManager
|
||||
* @Description: 文件远程管理
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/4 23:16
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class FileRemoteManager {
|
||||
|
||||
private static FileRemoteManager fileRemoteManager = FileRemoteManagerBuilder.fileRemoteManager;
|
||||
private Map<String, String> updateKeyValueMap = new ConcurrentHashMap<>();
|
||||
private IFileClientDao fileRemoteDao;
|
||||
|
||||
private FileRemoteManager() {
|
||||
|
||||
}
|
||||
|
||||
public static FileRemoteManager getInstance() {
|
||||
return fileRemoteManager;
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
updateKeyValueMap.clear();
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("status", "active");
|
||||
List<FileClientDTO> fileClientDTOS = fileRemoteDao.list(params);
|
||||
for (FileClientDTO fileClientDTO : fileClientDTOS) {
|
||||
updateKeyValueMap.put(fileClientDTO.getAccessKey(), fileClientDTO.getAccessSecret());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验
|
||||
*
|
||||
* @param updateKey
|
||||
* @param updateSecret
|
||||
* @return
|
||||
*/
|
||||
public boolean check(String updateKey, String updateSecret) {
|
||||
if (StringUtils.isBlank(updateKey) || StringUtils.isBlank(updateSecret)) {
|
||||
return false;
|
||||
}
|
||||
String existUpdateSecret = updateKeyValueMap.get(updateKey);
|
||||
if (!StringUtils.equals(updateSecret, existUpdateSecret)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setFileRemoteDao(IFileClientDao fileRemoteDao) {
|
||||
this.fileRemoteDao = fileRemoteDao;
|
||||
refresh();
|
||||
}
|
||||
|
||||
private static class FileRemoteManagerBuilder {
|
||||
public static FileRemoteManager fileRemoteManager = new FileRemoteManager();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package ink.wgink.module.file.pojo.dtos.fileclient;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* @ClassName: FileRemoteDTO
|
||||
* @Description: 文件远程
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/4 20:56
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@ApiModel
|
||||
public class FileClientDTO {
|
||||
|
||||
@ApiModelProperty(name = "fileClientId", value = "主键")
|
||||
private String fileClientId;
|
||||
@ApiModelProperty(name = "title", value = "标题")
|
||||
private String title;
|
||||
@ApiModelProperty(name = "accessKey", value = "上传Key")
|
||||
private String accessKey;
|
||||
@ApiModelProperty(name = "accessSecret", value = "上传秘钥")
|
||||
private String accessSecret;
|
||||
@ApiModelProperty(name = "status", value = "状态")
|
||||
private String status;
|
||||
@ApiModelProperty(name = "gmtCreate", value = "创建时间")
|
||||
private String gmtCreate;
|
||||
|
||||
public String getFileClientId() {
|
||||
return fileClientId == null ? "" : fileClientId.trim();
|
||||
}
|
||||
|
||||
public void setFileClientId(String fileClientId) {
|
||||
this.fileClientId = fileClientId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title == null ? "" : title.trim();
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getAccessKey() {
|
||||
return accessKey == null ? "" : accessKey.trim();
|
||||
}
|
||||
|
||||
public void setAccessKey(String accessKey) {
|
||||
this.accessKey = accessKey;
|
||||
}
|
||||
|
||||
public String getAccessSecret() {
|
||||
return accessSecret == null ? "" : accessSecret.trim();
|
||||
}
|
||||
|
||||
public void setAccessSecret(String accessSecret) {
|
||||
this.accessSecret = accessSecret;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status == null ? "" : status.trim();
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getGmtCreate() {
|
||||
return gmtCreate == null ? "" : gmtCreate.trim();
|
||||
}
|
||||
|
||||
public void setGmtCreate(String gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package ink.wgink.module.file.pojo.vos.fileremote;
|
||||
|
||||
import ink.wgink.annotation.CheckEmptyAnnotation;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* @ClassName: FileRemoteVO
|
||||
* @Description: 文件远程
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/4 21:35
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@ApiModel
|
||||
public class FileClientVO {
|
||||
|
||||
@ApiModelProperty(name = "title", value = "标题")
|
||||
@CheckEmptyAnnotation(name = "标题")
|
||||
private String title;
|
||||
@ApiModelProperty(name = "status", value = "状态")
|
||||
@CheckEmptyAnnotation(name = "状态")
|
||||
private String status;
|
||||
|
||||
public String getTitle() {
|
||||
return title == null ? "" : title.trim();
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status == null ? "" : status.trim();
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
@ -12,8 +12,10 @@ public class FileSaveVO {
|
||||
private String fileName;
|
||||
private String fileType;
|
||||
private String uploadPath;
|
||||
private String fileUrl;
|
||||
private long fileSize;
|
||||
private String creator;
|
||||
private String fileSummary;
|
||||
|
||||
public String getFileName() {
|
||||
return fileName == null ? "" : fileName.trim();
|
||||
@ -39,6 +41,14 @@ public class FileSaveVO {
|
||||
this.uploadPath = uploadPath;
|
||||
}
|
||||
|
||||
public String getFileUrl() {
|
||||
return fileUrl == null ? "" : fileUrl.trim();
|
||||
}
|
||||
|
||||
public void setFileUrl(String fileUrl) {
|
||||
this.fileUrl = fileUrl;
|
||||
}
|
||||
|
||||
public long getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
@ -54,4 +64,12 @@ public class FileSaveVO {
|
||||
public void setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public String getFileSummary() {
|
||||
return fileSummary == null ? "" : fileSummary.trim();
|
||||
}
|
||||
|
||||
public void setFileSummary(String fileSummary) {
|
||||
this.fileSummary = fileSummary;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
package ink.wgink.module.file.remote;
|
||||
|
||||
import ink.wgink.annotation.rpc.rest.RemoteService;
|
||||
import ink.wgink.annotation.rpc.rest.method.RemotePostMethod;
|
||||
import ink.wgink.annotation.rpc.rest.params.RemoteFileInputStreamParams;
|
||||
import ink.wgink.annotation.rpc.rest.params.RemoteFormParams;
|
||||
import ink.wgink.annotation.rpc.rest.params.RemoteHeaderParams;
|
||||
import ink.wgink.annotation.rpc.rest.params.RemoteServerParams;
|
||||
import ink.wgink.common.rpc.rest.pojo.RemoteFileInputStream;
|
||||
import ink.wgink.module.file.pojo.dtos.v2.FileUploadSuccessDTO;
|
||||
|
||||
/**
|
||||
* @ClassName: IFileCenterUploadService
|
||||
* @Description: 文件中心上传
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/4 15:00
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@RemoteService
|
||||
public interface IFileCenterRemoteService {
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*
|
||||
* @param server
|
||||
* @param accessKey
|
||||
* @param accessSecret
|
||||
* @param remoteFileInputStream
|
||||
* @param creator
|
||||
* @return
|
||||
*/
|
||||
@RemotePostMethod("/app/file-center/upload-file")
|
||||
FileUploadSuccessDTO uploadFile(@RemoteServerParams String server,
|
||||
@RemoteHeaderParams("Access-Key") String accessKey,
|
||||
@RemoteHeaderParams("Access-Secret") String accessSecret,
|
||||
@RemoteFileInputStreamParams("file") RemoteFileInputStream remoteFileInputStream,
|
||||
@RemoteFormParams("creator") String creator);
|
||||
|
||||
/**
|
||||
* 上传图片
|
||||
*
|
||||
* @param server
|
||||
* @param accessKey
|
||||
* @param accessSecret
|
||||
* @param remoteFileInputStream
|
||||
* @param creator
|
||||
* @return
|
||||
*/
|
||||
@RemotePostMethod("/app/file-center/upload-image")
|
||||
FileUploadSuccessDTO uploadImage(@RemoteServerParams String server,
|
||||
@RemoteHeaderParams("Access-Key") String accessKey,
|
||||
@RemoteHeaderParams("Access-Secret") String accessSecret,
|
||||
@RemoteFileInputStreamParams("image") RemoteFileInputStream remoteFileInputStream,
|
||||
@RemoteFormParams("creator") String creator);
|
||||
|
||||
/**
|
||||
* 上传音频
|
||||
*
|
||||
* @param server
|
||||
* @param accessKey
|
||||
* @param accessSecret
|
||||
* @param remoteFileInputStream
|
||||
* @param creator
|
||||
* @return
|
||||
*/
|
||||
@RemotePostMethod("/app/file-center/upload-audio")
|
||||
FileUploadSuccessDTO uploadAudio(@RemoteServerParams String server,
|
||||
@RemoteHeaderParams("Access-Key") String accessKey,
|
||||
@RemoteHeaderParams("Access-Secret") String accessSecret,
|
||||
@RemoteFileInputStreamParams("audio") RemoteFileInputStream remoteFileInputStream,
|
||||
@RemoteFormParams("creator") String creator);
|
||||
|
||||
/**
|
||||
* 上传视频
|
||||
*
|
||||
* @param server
|
||||
* @param accessKey
|
||||
* @param accessSecret
|
||||
* @param remoteFileInputStream
|
||||
* @param creator
|
||||
* @return
|
||||
*/
|
||||
@RemotePostMethod("/app/file-center/upload-video")
|
||||
FileUploadSuccessDTO uploadVideo(@RemoteServerParams String server,
|
||||
@RemoteHeaderParams("Access-Key") String accessKey,
|
||||
@RemoteHeaderParams("Access-Secret") String accessSecret,
|
||||
@RemoteFileInputStreamParams("video") RemoteFileInputStream remoteFileInputStream,
|
||||
@RemoteFormParams("creator") String creator);
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package ink.wgink.module.file.service.filecenter;
|
||||
|
||||
import ink.wgink.module.file.enums.UploadTypeEnum;
|
||||
import ink.wgink.module.file.pojo.dtos.v2.FileUploadSuccessDTO;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* @ClassName: IFileCenterService
|
||||
* @Description: 文件中心
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/6 13:36
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public interface IFileCenterService {
|
||||
|
||||
/**
|
||||
* 单文件上传
|
||||
*
|
||||
* @param userId
|
||||
* @param uploadFile
|
||||
* @param uploadTypeEnum
|
||||
* @return
|
||||
*/
|
||||
FileUploadSuccessDTO uploadSingleByUserId(String userId, MultipartFile uploadFile, UploadTypeEnum uploadTypeEnum);
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
package ink.wgink.module.file.service.filecenter.impl;
|
||||
|
||||
import ink.wgink.common.base.DefaultBaseService;
|
||||
import ink.wgink.exceptions.FileException;
|
||||
import ink.wgink.exceptions.SearchException;
|
||||
import ink.wgink.module.file.enums.UploadTypeEnum;
|
||||
import ink.wgink.module.file.pojo.dtos.v2.FileUploadSuccessDTO;
|
||||
import ink.wgink.module.file.pojo.vos.v2.FileSaveVO;
|
||||
import ink.wgink.module.file.service.filecenter.IFileCenterService;
|
||||
import ink.wgink.module.file.service.filedownload.IFileDownloadService;
|
||||
import ink.wgink.module.file.service.v2.IFileService;
|
||||
import ink.wgink.pojo.pos.FilePO;
|
||||
import ink.wgink.util.request.StaticResourceRequestUtil;
|
||||
import org.apache.catalina.connector.ClientAbortException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
/**
|
||||
* @ClassName: FileCenterServiceImpl
|
||||
* @Description: 文件中心
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/6 13:36
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Service
|
||||
public class FileCenterServiceImpl extends DefaultBaseService implements IFileCenterService {
|
||||
|
||||
@Autowired
|
||||
private IFileService fileService;
|
||||
@Autowired
|
||||
private IFileDownloadService fileDownloadService;
|
||||
|
||||
@Override
|
||||
public FileUploadSuccessDTO uploadSingleByUserId(String userId, MultipartFile uploadFile, UploadTypeEnum uploadTypeEnum) {
|
||||
FileSaveVO fileSaveVO = getCenterFileSaveVO(uploadFile, uploadTypeEnum, userId);
|
||||
return fileService.saveFile(fileSaveVO);
|
||||
}
|
||||
|
||||
private void download(HttpServletRequest request, HttpServletResponse response, String fileId) {
|
||||
FilePO filePO = fileService.getPO(fileId);
|
||||
try (
|
||||
RandomAccessFile randomAccessFile = new RandomAccessFile(filePO.getFilePath(), "r");
|
||||
FileChannel fileChannel = randomAccessFile.getChannel();
|
||||
OutputStream outputStream = response.getOutputStream();
|
||||
WritableByteChannel writableByteChannel = Channels.newChannel(outputStream);
|
||||
) {
|
||||
response.setHeader("Content-Length", filePO.getFileSize().toString());
|
||||
response.setContentType(StaticResourceRequestUtil.getContentType(filePO.getFileType()));
|
||||
response.setHeader("Content-Disposition", "inline;fileName=" + URLEncoder.encode(filePO.getFileName(), "UTF-8"));
|
||||
String rangeString = request.getHeader("Range");
|
||||
long contentLength = filePO.getFileSize();
|
||||
long startRange = 0;
|
||||
long endRange = contentLength - 1;
|
||||
if (!StringUtils.isBlank(rangeString)) {
|
||||
response.setContentType("multipart/byteranges");
|
||||
String[] rangeArray = rangeString.substring(rangeString.indexOf("=") + 1).split("-");
|
||||
startRange = Long.parseLong(rangeArray[0]);
|
||||
if (rangeArray.length > 1) {
|
||||
endRange = Long.parseLong(rangeArray[1]);
|
||||
}
|
||||
response.setHeader("Content-Length", String.valueOf(endRange - startRange + 1));
|
||||
response.setHeader("Content-Range", String.format("bytes %d-%d/%d", startRange, endRange, contentLength));
|
||||
response.setHeader("Accept-Ranges", "bytes");
|
||||
response.setHeader("Etag", fileId);
|
||||
response.setStatus(206);
|
||||
randomAccessFile.seek(startRange);
|
||||
}
|
||||
LOG.debug("startRange: {}, endRange: {}", startRange, endRange);
|
||||
long totalOutputLength = endRange - startRange + 1;
|
||||
fileChannel.transferTo(startRange, totalOutputLength, writableByteChannel);
|
||||
outputStream.flush();
|
||||
if (endRange >= contentLength - 1) {
|
||||
fileDownloadService.handle(request, false, fileId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (e instanceof ClientAbortException) {
|
||||
LOG.debug("客户端断开连接");
|
||||
} else {
|
||||
throw new FileException("文件输出异常", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件保存VO
|
||||
*
|
||||
* @param uploadFile
|
||||
* @param uploadTypeEnum
|
||||
* @return
|
||||
*/
|
||||
private FileSaveVO getCenterFileSaveVO(MultipartFile uploadFile, UploadTypeEnum uploadTypeEnum, String creator) {
|
||||
String fileName = uploadFile.getOriginalFilename();
|
||||
InputStream inputStream;
|
||||
try {
|
||||
inputStream = uploadFile.getInputStream();
|
||||
} catch (IOException e) {
|
||||
throw new SearchException(e);
|
||||
}
|
||||
return fileService.getCenterFileSaveVO(inputStream, uploadTypeEnum, fileName, creator);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package ink.wgink.module.file.service.fileclient;
|
||||
|
||||
import ink.wgink.module.file.pojo.dtos.fileclient.FileClientDTO;
|
||||
import ink.wgink.module.file.pojo.vos.fileremote.FileClientVO;
|
||||
import ink.wgink.pojo.ListPage;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName: IFileRemoteService
|
||||
* @Description: 文件远程
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/4 21:32
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public interface IFileClientService {
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @param fileClientVO
|
||||
*/
|
||||
void save(FileClientVO fileClientVO);
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param ids
|
||||
*/
|
||||
void remove(List<String> ids);
|
||||
|
||||
/**
|
||||
* 更新状态
|
||||
*
|
||||
* @param fileRemoteId
|
||||
* @param fileClientVO
|
||||
*/
|
||||
void update(String fileRemoteId, FileClientVO fileClientVO);
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
FileClientDTO get(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*
|
||||
* @param fileRemoteId
|
||||
* @return
|
||||
*/
|
||||
FileClientDTO get(String fileRemoteId);
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
List<FileClientDTO> list(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 分页列表
|
||||
*
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
SuccessResultList<List<FileClientDTO>> listPage(ListPage page);
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package ink.wgink.module.file.service.fileclient.impl;
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import ink.wgink.common.base.DefaultBaseService;
|
||||
import ink.wgink.module.file.dao.fileclient.IFileClientDao;
|
||||
import ink.wgink.module.file.manager.FileRemoteManager;
|
||||
import ink.wgink.module.file.pojo.dtos.fileclient.FileClientDTO;
|
||||
import ink.wgink.module.file.pojo.vos.fileremote.FileClientVO;
|
||||
import ink.wgink.module.file.service.fileclient.IFileClientService;
|
||||
import ink.wgink.pojo.ListPage;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
import ink.wgink.util.UUIDUtil;
|
||||
import ink.wgink.util.map.HashMapUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName: FileRemoteServiceImpl
|
||||
* @Description: 文件远程
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/4 21:33
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Service
|
||||
public class FileClientServiceImpl extends DefaultBaseService implements IFileClientService {
|
||||
|
||||
@Autowired
|
||||
private IFileClientDao fileRemoteDao;
|
||||
|
||||
@Override
|
||||
public void save(FileClientVO fileClientVO) {
|
||||
Map<String, Object> params = HashMapUtil.beanToMap(fileClientVO);
|
||||
params.put("fileClientId", UUIDUtil.getUUID());
|
||||
params.put("accessKey", UUIDUtil.getUUID());
|
||||
params.put("accessSecret", UUIDUtil.get32UUID() + UUIDUtil.get32UUID());
|
||||
setSaveInfo(params);
|
||||
params.put("isDelete", 0);
|
||||
fileRemoteDao.save(params);
|
||||
|
||||
FileRemoteManager.getInstance().refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(List<String> ids) {
|
||||
Map<String, Object> params = getHashMap(2);
|
||||
params.put("fileClientIds", ids);
|
||||
fileRemoteDao.remove(params);
|
||||
|
||||
FileRemoteManager.getInstance().refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(String fileClientId, FileClientVO fileClientVO) {
|
||||
Map<String, Object> params = HashMapUtil.beanToMap(fileClientVO);
|
||||
params.put("fileClientId", fileClientId);
|
||||
setUpdateInfo(params);
|
||||
fileRemoteDao.update(params);
|
||||
|
||||
FileRemoteManager.getInstance().refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileClientDTO get(Map<String, Object> params) {
|
||||
params = params == null ? getHashMap(0) : params;
|
||||
return fileRemoteDao.get(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileClientDTO get(String fileClientId) {
|
||||
Map<String, Object> params = getHashMap(2);
|
||||
params.put("fileClientId", fileClientId);
|
||||
return fileRemoteDao.get(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileClientDTO> list(Map<String, Object> params) {
|
||||
return fileRemoteDao.list(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuccessResultList<List<FileClientDTO>> listPage(ListPage page) {
|
||||
PageHelper.startPage(page.getPage(), page.getRows());
|
||||
List<FileClientDTO> fileClientDTOS = list(page.getParams());
|
||||
PageInfo<FileClientDTO> pageInfo = new PageInfo<>(fileClientDTOS);
|
||||
return new SuccessResultList<>(fileClientDTOS, pageInfo.getPageNum(), pageInfo.getTotal());
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import ink.wgink.module.file.pojo.vos.filedownload.FileDownloadVO;
|
||||
import ink.wgink.pojo.ListPage;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -66,4 +67,13 @@ public interface IFileDownloadService {
|
||||
*/
|
||||
Integer countByFileId(String fileId);
|
||||
|
||||
/**
|
||||
* 下载
|
||||
*
|
||||
* @param httpServletRequest
|
||||
* @param isOpen 是否打开
|
||||
* @param fileId
|
||||
*/
|
||||
void handle(HttpServletRequest httpServletRequest, boolean isOpen, String fileId);
|
||||
|
||||
}
|
||||
|
@ -12,9 +12,13 @@ import ink.wgink.pojo.result.SuccessResultList;
|
||||
import ink.wgink.util.UUIDUtil;
|
||||
import ink.wgink.util.date.DateUtil;
|
||||
import ink.wgink.util.map.HashMapUtil;
|
||||
import ink.wgink.util.request.RequestUtil;
|
||||
import ink.wgink.util.thread.CachedThreadPoolUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -73,5 +77,16 @@ public class FileDownloadServiceImpl extends DefaultBaseService implements IFile
|
||||
return fileDownloadDao.count(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(HttpServletRequest httpServletRequest, boolean isOpen, String fileId) {
|
||||
String requestIp = RequestUtil.getRequestIp(httpServletRequest);
|
||||
if (!isOpen && !StringUtils.isBlank(requestIp)) {
|
||||
// 记录下载历史
|
||||
CachedThreadPoolUtil.execute(() -> {
|
||||
save(new FileDownloadVO(fileId, requestIp));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ import java.util.Map;
|
||||
*/
|
||||
public interface IFileService {
|
||||
|
||||
String FILE_SUMMARY_LOCAL = "local";
|
||||
String FILE_SUMMARY_CENTER = "center";
|
||||
|
||||
/**
|
||||
* 单文件上传
|
||||
*
|
||||
@ -151,4 +154,14 @@ public interface IFileService {
|
||||
*/
|
||||
SuccessResultList<List<FileInfoDTO>> listPage(ListPage page);
|
||||
|
||||
/**
|
||||
* 获取文件保存VO
|
||||
*
|
||||
* @param inputStream
|
||||
* @param uploadTypeEnum
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
FileSaveVO getCenterFileSaveVO(InputStream inputStream, UploadTypeEnum uploadTypeEnum, String fileName, String creator);
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package ink.wgink.module.file.service.v2.impl;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import ink.wgink.common.base.DefaultBaseService;
|
||||
import ink.wgink.common.rpc.rest.pojo.RemoteFileInputStream;
|
||||
import ink.wgink.exceptions.FileException;
|
||||
import ink.wgink.exceptions.SearchException;
|
||||
import ink.wgink.module.file.components.FileComponent;
|
||||
@ -11,18 +12,19 @@ import ink.wgink.module.file.enums.UploadTypeEnum;
|
||||
import ink.wgink.module.file.manager.FilesManager;
|
||||
import ink.wgink.module.file.pojo.dtos.FileInfoDTO;
|
||||
import ink.wgink.module.file.pojo.dtos.v2.FileUploadSuccessDTO;
|
||||
import ink.wgink.module.file.pojo.vos.filedownload.FileDownloadVO;
|
||||
import ink.wgink.module.file.pojo.vos.v2.FileSaveVO;
|
||||
import ink.wgink.module.file.pojo.vos.v2.FileUpdateVO;
|
||||
import ink.wgink.module.file.remote.IFileCenterRemoteService;
|
||||
import ink.wgink.module.file.service.filedownload.IFileDownloadService;
|
||||
import ink.wgink.module.file.service.v2.IFileService;
|
||||
import ink.wgink.module.file.utils.FileUtil;
|
||||
import ink.wgink.pojo.ListPage;
|
||||
import ink.wgink.pojo.pos.FilePO;
|
||||
import ink.wgink.pojo.result.SuccessResultList;
|
||||
import ink.wgink.properties.FileCenterProperties;
|
||||
import ink.wgink.properties.FileProperties;
|
||||
import ink.wgink.util.UUIDUtil;
|
||||
import ink.wgink.util.date.DateUtil;
|
||||
import ink.wgink.util.request.RequestUtil;
|
||||
import ink.wgink.util.thread.CachedThreadPoolUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -48,67 +50,65 @@ import java.util.Map;
|
||||
@Service("fileServiceV2")
|
||||
public class FileServiceImpl extends DefaultBaseService implements IFileService {
|
||||
|
||||
@Autowired
|
||||
private FileProperties fileProperties;
|
||||
@Autowired
|
||||
private FileComponent fileComponent;
|
||||
@Autowired
|
||||
private IFileDao fileDao;
|
||||
@Autowired
|
||||
private IFileDownloadService fileDownloadService;
|
||||
@Autowired
|
||||
private IFileCenterRemoteService fileUploadCenterService;
|
||||
|
||||
@Override
|
||||
public FileUploadSuccessDTO uploadSingle(MultipartFile uploadFile, UploadTypeEnum uploadTypeEnum) {
|
||||
FileSaveVO fileSaveVO = getFileSaveVO(uploadFile, uploadTypeEnum);
|
||||
fileSaveVO.setCreator(securityComponent.getCurrentUser().getUserId());
|
||||
FileSaveVO fileSaveVO = getCenterFileSaveVO(uploadFile, uploadTypeEnum, securityComponent.getCurrentUser().getUserId());
|
||||
return saveFile(fileSaveVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUploadSuccessDTO uploadSingle(InputStream inputStream, UploadTypeEnum uploadTypeEnum, String fileName) {
|
||||
FileSaveVO fileSaveVO = getFileSaveVO(inputStream, uploadTypeEnum, fileName);
|
||||
fileSaveVO.setCreator(securityComponent.getCurrentUser().getUserId());
|
||||
FileSaveVO fileSaveVO = getCenterFileSaveVO(inputStream, uploadTypeEnum, fileName, securityComponent.getCurrentUser().getUserId());
|
||||
return saveFile(fileSaveVO);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public FileUploadSuccessDTO uploadSingleByToken(String token, MultipartFile uploadFile, UploadTypeEnum uploadTypeEnum) {
|
||||
FileSaveVO fileSaveVO = getFileSaveVO(uploadFile, uploadTypeEnum);
|
||||
fileSaveVO.setCreator(getAppTokenUser(token).getId());
|
||||
FileSaveVO fileSaveVO = getCenterFileSaveVO(uploadFile, uploadTypeEnum, getAppTokenUser(token).getId());
|
||||
return saveFile(fileSaveVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUploadSuccessDTO uploadSingleByToken(String token, InputStream inputStream, UploadTypeEnum uploadTypeEnum, String fileName) {
|
||||
FileSaveVO fileSaveVO = getFileSaveVO(inputStream, uploadTypeEnum, fileName);
|
||||
fileSaveVO.setCreator(getAppTokenUser(token).getId());
|
||||
FileSaveVO fileSaveVO = getCenterFileSaveVO(inputStream, uploadTypeEnum, fileName, getAppTokenUser(token).getId());
|
||||
return saveFile(fileSaveVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUploadSuccessDTO uploadSingleByUserId(String userId, MultipartFile uploadFile, UploadTypeEnum uploadTypeEnum) {
|
||||
FileSaveVO fileSaveVO = getFileSaveVO(uploadFile, uploadTypeEnum);
|
||||
fileSaveVO.setCreator(userId);
|
||||
FileSaveVO fileSaveVO = getCenterFileSaveVO(uploadFile, uploadTypeEnum, userId);
|
||||
return saveFile(fileSaveVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUploadSuccessDTO uploadSingleByUserId(String userId, InputStream inputStream, UploadTypeEnum uploadTypeEnum, String fileName) {
|
||||
FileSaveVO fileSaveVO = getFileSaveVO(inputStream, uploadTypeEnum, fileName);
|
||||
fileSaveVO.setCreator(userId);
|
||||
FileSaveVO fileSaveVO = getCenterFileSaveVO(inputStream, uploadTypeEnum, fileName, userId);
|
||||
return saveFile(fileSaveVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUploadSuccessDTO saveFile(FileSaveVO fileSaveVO) {
|
||||
String fileUrl = fileComponent.getFileUrl(fileSaveVO.getUploadPath());
|
||||
String fileId = UUIDUtil.getUUID();
|
||||
Map<String, Object> params = getHashMap(10);
|
||||
params.put("fileId", fileId);
|
||||
params.put("fileName", fileSaveVO.getFileName());
|
||||
params.put("filePath", fileSaveVO.getUploadPath());
|
||||
params.put("fileUrl", fileUrl);
|
||||
params.put("fileUrl", fileSaveVO.getFileUrl());
|
||||
params.put("fileType", fileSaveVO.getFileType());
|
||||
params.put("fileSize", fileSaveVO.getFileSize());
|
||||
params.put("fileSummary", fileSaveVO.getFileSummary());
|
||||
params.put("isBack", 0);
|
||||
|
||||
String time = DateUtil.getTime();
|
||||
@ -119,7 +119,7 @@ public class FileServiceImpl extends DefaultBaseService implements IFileService
|
||||
params.put("isDelete", 0);
|
||||
fileDao.save(params);
|
||||
|
||||
return new FileUploadSuccessDTO(fileId, fileSaveVO.getFileName(), fileSaveVO.getFileSize(), fileUrl);
|
||||
return new FileUploadSuccessDTO(fileId, fileSaveVO.getFileName(), fileSaveVO.getFileSize(), fileSaveVO.getFileUrl());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -179,16 +179,9 @@ public class FileServiceImpl extends DefaultBaseService implements IFileService
|
||||
throw new FileException("文件不存在");
|
||||
}
|
||||
try {
|
||||
String requestIp = RequestUtil.getRequestIp(request);
|
||||
String code = FilesManager.getInstance().generateCode(fileId, filePO.getFileName());
|
||||
response.sendRedirect(String.format("%s/%s?file=%s&code=%s&open=%d", request.getContextPath(), filePO.getFileUrl(), fileId, code, isOpen ? 1 : 0));
|
||||
if (!isOpen && !StringUtils.isBlank(requestIp)) {
|
||||
// 记录下载历史
|
||||
CachedThreadPoolUtil.execute(() -> {
|
||||
FileDownloadVO fileDownloadVO = new FileDownloadVO(filePO.getFileId(), requestIp);
|
||||
fileDownloadService.save(fileDownloadVO);
|
||||
});
|
||||
}
|
||||
fileDownloadService.handle(request, isOpen, fileId);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@ -212,6 +205,24 @@ public class FileServiceImpl extends DefaultBaseService implements IFileService
|
||||
return new SuccessResultList<>(fileInfoDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileSaveVO getCenterFileSaveVO(InputStream inputStream, UploadTypeEnum uploadTypeEnum, String fileName, String creator) {
|
||||
String fileType = fileComponent.getFileType(fileName);
|
||||
String uploadPath = fileComponent.getUploadPath(uploadTypeEnum, fileType);
|
||||
String uuidFileName = UUIDUtil.get32UUID() + "." + fileType;
|
||||
long fileSize = FileUtil.save(inputStream, uuidFileName, uploadPath);
|
||||
// 保存文件
|
||||
FileSaveVO fileSaveVO = new FileSaveVO();
|
||||
fileSaveVO.setFileName(fileName);
|
||||
fileSaveVO.setFileType(fileType);
|
||||
fileSaveVO.setUploadPath(uploadPath + File.separator + uuidFileName);
|
||||
fileSaveVO.setFileUrl(fileComponent.getFileUrl(fileSaveVO.getUploadPath()));
|
||||
fileSaveVO.setFileSize(fileSize);
|
||||
fileSaveVO.setCreator(creator);
|
||||
fileSaveVO.setFileSummary(FILE_SUMMARY_LOCAL);
|
||||
return fileSaveVO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置查询文件类型
|
||||
*
|
||||
@ -256,7 +267,7 @@ public class FileServiceImpl extends DefaultBaseService implements IFileService
|
||||
* @param uploadTypeEnum
|
||||
* @return
|
||||
*/
|
||||
private FileSaveVO getFileSaveVO(MultipartFile uploadFile, UploadTypeEnum uploadTypeEnum) {
|
||||
private FileSaveVO getCenterFileSaveVO(MultipartFile uploadFile, UploadTypeEnum uploadTypeEnum, String creator) {
|
||||
String fileName = uploadFile.getOriginalFilename();
|
||||
InputStream inputStream;
|
||||
try {
|
||||
@ -264,28 +275,66 @@ public class FileServiceImpl extends DefaultBaseService implements IFileService
|
||||
} catch (IOException e) {
|
||||
throw new SearchException(e);
|
||||
}
|
||||
return getFileSaveVO(inputStream, uploadTypeEnum, fileName);
|
||||
// 上传到文件中心
|
||||
if (fileProperties.getCenter() != null) {
|
||||
return getCenterFileSaveVO(inputStream, uploadTypeEnum, fileName, uploadFile.getSize(), creator);
|
||||
}
|
||||
return getCenterFileSaveVO(inputStream, uploadTypeEnum, fileName, creator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件保存VO
|
||||
* 上传文件到文件中心
|
||||
*
|
||||
* @param inputStream
|
||||
* @param uploadTypeEnum
|
||||
* @param fileName
|
||||
* @param fileSize
|
||||
* @param creator
|
||||
* @return
|
||||
*/
|
||||
private FileSaveVO getFileSaveVO(InputStream inputStream, UploadTypeEnum uploadTypeEnum, String fileName) {
|
||||
private FileSaveVO getCenterFileSaveVO(InputStream inputStream, UploadTypeEnum uploadTypeEnum, String fileName, long fileSize, String creator) {
|
||||
RemoteFileInputStream remoteFileInputStream = new RemoteFileInputStream();
|
||||
remoteFileInputStream.setInputStream(inputStream);
|
||||
remoteFileInputStream.setFileName(fileName);
|
||||
remoteFileInputStream.setFileSize(fileSize);
|
||||
|
||||
String fileType = fileComponent.getFileType(fileName);
|
||||
String uploadPath = fileComponent.getUploadPath(uploadTypeEnum, fileType);
|
||||
String uuidFileName = UUIDUtil.get32UUID() + "." + fileType;
|
||||
long fileSize = fileComponent.saveFile(inputStream, uuidFileName, uploadPath);
|
||||
// 保存文件
|
||||
FileCenterProperties fileCenterProperties = fileProperties.getCenter();
|
||||
FileUploadSuccessDTO fileUploadSuccessDTO;
|
||||
if (UploadTypeEnum.IMAGE.equals(uploadTypeEnum)) {
|
||||
fileUploadSuccessDTO = fileUploadCenterService.uploadImage(fileCenterProperties.getUploadUrl(),
|
||||
fileCenterProperties.getAccessKey(),
|
||||
fileCenterProperties.getAccessSecret(),
|
||||
remoteFileInputStream,
|
||||
creator);
|
||||
} else if (UploadTypeEnum.VIDEO.equals(uploadTypeEnum)) {
|
||||
fileUploadSuccessDTO = fileUploadCenterService.uploadVideo(fileCenterProperties.getUploadUrl(),
|
||||
fileCenterProperties.getAccessKey(),
|
||||
fileCenterProperties.getAccessSecret(),
|
||||
remoteFileInputStream,
|
||||
creator);
|
||||
} else if (UploadTypeEnum.AUDIO.equals(uploadTypeEnum)) {
|
||||
fileUploadSuccessDTO = fileUploadCenterService.uploadAudio(fileCenterProperties.getUploadUrl(),
|
||||
fileCenterProperties.getAccessKey(),
|
||||
fileCenterProperties.getAccessSecret(),
|
||||
remoteFileInputStream,
|
||||
creator);
|
||||
} else {
|
||||
fileUploadSuccessDTO = fileUploadCenterService.uploadFile(fileCenterProperties.getUploadUrl(),
|
||||
fileCenterProperties.getAccessKey(),
|
||||
fileCenterProperties.getAccessSecret(),
|
||||
remoteFileInputStream,
|
||||
creator);
|
||||
}
|
||||
|
||||
FileSaveVO fileSaveVO = new FileSaveVO();
|
||||
fileSaveVO.setFileName(fileName);
|
||||
fileSaveVO.setUploadPath(fileCenterProperties.getUploadUrl());
|
||||
fileSaveVO.setFileUrl(fileUploadSuccessDTO.getFileUrl());
|
||||
fileSaveVO.setFileType(fileType);
|
||||
fileSaveVO.setUploadPath(uploadPath + File.separator + uuidFileName);
|
||||
fileSaveVO.setFileSize(fileSize);
|
||||
fileSaveVO.setFileName(fileName);
|
||||
fileSaveVO.setCreator(creator);
|
||||
fileSaveVO.setFileSummary(FILE_SUMMARY_CENTER);
|
||||
return fileSaveVO;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
package ink.wgink.module.file.startup;
|
||||
|
||||
import ink.wgink.interfaces.manager.IFilesShowCodeService;
|
||||
import ink.wgink.module.file.dao.fileclient.IFileClientDao;
|
||||
import ink.wgink.module.file.manager.FileRemoteManager;
|
||||
import ink.wgink.module.file.manager.FilesManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
@ -20,10 +22,13 @@ public class FilesStartUp implements ApplicationRunner {
|
||||
|
||||
@Autowired
|
||||
private IFilesShowCodeService filesShowCodeService;
|
||||
@Autowired
|
||||
private IFileClientDao fileRemoteDao;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
FilesManager.getInstance().setFilesShowCodeService(filesShowCodeService);
|
||||
FileRemoteManager.getInstance().setFileRemoteDao(fileRemoteDao);
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0/1 * * * ?")
|
||||
|
@ -0,0 +1,119 @@
|
||||
package ink.wgink.module.file.utils;
|
||||
|
||||
import ink.wgink.exceptions.FileException;
|
||||
import ink.wgink.exceptions.SearchException;
|
||||
import ink.wgink.exceptions.base.SystemException;
|
||||
import ink.wgink.module.file.service.IFileService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* @ClassName: FileSaveUtil
|
||||
* @Description: 保存文件工具
|
||||
* @Author: wanggeng
|
||||
* @Date: 2022/8/3 21:12
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class FileUtil {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FileUtil.class);
|
||||
private static final char[] HEX_CODE = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
|
||||
/**
|
||||
* 保存文件
|
||||
*
|
||||
* @param fileInputStream 文件流
|
||||
* @param fileName 文件名
|
||||
* @param filePath 保存路径
|
||||
* @return 文件大小
|
||||
*/
|
||||
public static long save(InputStream fileInputStream, String fileName, String filePath) {
|
||||
File uploadFolder = new File(filePath);
|
||||
if (!uploadFolder.exists()) {
|
||||
uploadFolder.mkdirs();
|
||||
}
|
||||
FileOutputStream uploadFileOutputStream = null;
|
||||
long fileSize = 0;
|
||||
try {
|
||||
uploadFileOutputStream = new FileOutputStream(uploadFolder + File.separator + fileName);
|
||||
int readLength;
|
||||
for (byte[] buf = new byte[IFileService.INPUT_STREAM_SIZE]; (readLength = fileInputStream.read(buf)) > -1; ) {
|
||||
uploadFileOutputStream.write(buf, 0, readLength);
|
||||
fileSize += readLength;
|
||||
}
|
||||
uploadFileOutputStream.flush();
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
throw new FileException("文件上传失败");
|
||||
} finally {
|
||||
try {
|
||||
if (null != uploadFileOutputStream) {
|
||||
uploadFileOutputStream.close();
|
||||
}
|
||||
if (null != fileInputStream) {
|
||||
fileInputStream.close();
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
LOG.error(e1.getMessage());
|
||||
throw new FileException("文件上传失败");
|
||||
}
|
||||
}
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除源文件
|
||||
*
|
||||
* @param sourceFilePath
|
||||
*/
|
||||
public static boolean delete(String sourceFilePath) {
|
||||
File file = new File(sourceFilePath);
|
||||
if (file.exists()) {
|
||||
return file.delete();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件的MD5
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
public static String getMD5(File file) {
|
||||
if (file == null) {
|
||||
throw new SearchException("文件不存在");
|
||||
}
|
||||
if (!file.exists()) {
|
||||
throw new SearchException("文件不存在");
|
||||
}
|
||||
String fileMd5;
|
||||
try (InputStream inputStream = Files.newInputStream(file.toPath())) {
|
||||
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
|
||||
int readLength;
|
||||
for (byte[] buf = new byte[IFileService.INPUT_STREAM_SIZE]; (readLength = inputStream.read(buf)) > -1; ) {
|
||||
messageDigest.update(buf, 0, readLength);
|
||||
}
|
||||
// 计算文件的MD5
|
||||
byte[] data = messageDigest.digest();
|
||||
StringBuilder fileMd5SB = new StringBuilder(data.length * 2);
|
||||
for (byte b : data) {
|
||||
fileMd5SB.append(HEX_CODE[(b >> 4) & 0xF]);
|
||||
fileMd5SB.append(HEX_CODE[(b & 0xF)]);
|
||||
}
|
||||
fileMd5 = fileMd5SB.toString();
|
||||
} catch (IOException | NoSuchAlgorithmException e) {
|
||||
throw new SystemException(e);
|
||||
}
|
||||
return fileMd5;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="ink.wgink.module.file.dao.fileclient.IFileClientDao">
|
||||
|
||||
<resultMap id="fileClientDTO" type="ink.wgink.module.file.pojo.dtos.fileclient.FileClientDTO">
|
||||
<id property="fileClientId" column="file_client_id"/>
|
||||
<result property="accessKey" column="access_key"/>
|
||||
<result property="accessSecret" column="access_secret"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="gmtCreate" column="gmt_create"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 建表 -->
|
||||
<update id="createTable">
|
||||
CREATE TABLE IF NOT EXISTS `sys_file_client` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`file_client_id` char(36) DEFAULT NULL COMMENT '主键',
|
||||
`title` varchar(255) DEFAULT NULL COMMENT '标题',
|
||||
`access_key` varchar(255) DEFAULT NULL COMMENT '上传Key',
|
||||
`access_secret` varchar(255) DEFAULT NULL COMMENT '上传密码',
|
||||
`status` varchar(255) DEFAULT NULL COMMENT '状态',
|
||||
`gmt_create` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`creator` char(36) DEFAULT NULL COMMENT '创建人',
|
||||
`gmt_modified` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
`modifier` char(36) DEFAULT NULL COMMENT '修改人',
|
||||
`is_delete` int(1) DEFAULT '0' COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `file_client_id` (`file_client_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件远程调用';
|
||||
</update>
|
||||
|
||||
<!-- 保存文件 -->
|
||||
<insert id="save" parameterType="map">
|
||||
INSERT INTO sys_file_client (
|
||||
file_client_id,
|
||||
title,
|
||||
access_key,
|
||||
access_secret,
|
||||
status,
|
||||
gmt_create,
|
||||
creator,
|
||||
gmt_modified,
|
||||
modifier,
|
||||
is_delete
|
||||
) VALUES(
|
||||
#{fileClientId},
|
||||
#{title},
|
||||
#{accessKey},
|
||||
#{accessSecret},
|
||||
#{status},
|
||||
#{gmtCreate},
|
||||
#{creator},
|
||||
#{gmtModified},
|
||||
#{modifier},
|
||||
#{isDelete}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<!-- 删除 -->
|
||||
<update id="remove" parameterType="map">
|
||||
UPDATE
|
||||
sys_file_client
|
||||
SET
|
||||
gmt_modified = #{gmtModified},
|
||||
modifier = #{modifier},
|
||||
is_delete = 0
|
||||
</update>
|
||||
|
||||
<!-- 修改状态 -->
|
||||
<update id="update" parameterType="map">
|
||||
UPDATE
|
||||
sys_file_client
|
||||
SET
|
||||
title = #{title},
|
||||
status = #{status},
|
||||
gmt_modified = #{gmtModified},
|
||||
modifier = #{modifier}
|
||||
WHERE
|
||||
file_client_id = #{fileClientId}
|
||||
</update>
|
||||
|
||||
<!-- 文件列表 -->
|
||||
<select id="get" parameterType="map" resultMap="fileClientDTO">
|
||||
SELECT
|
||||
file_client_id,
|
||||
title,
|
||||
access_key,
|
||||
access_secret,
|
||||
status,
|
||||
gmt_create
|
||||
FROM
|
||||
sys_file_client
|
||||
WHERE
|
||||
file_client_id = #{fileClientId}
|
||||
</select>
|
||||
|
||||
<!-- 文件列表 -->
|
||||
<select id="list" parameterType="map" resultMap="fileClientDTO">
|
||||
SELECT
|
||||
file_client_id,
|
||||
title,
|
||||
access_key,
|
||||
access_secret,
|
||||
status,
|
||||
gmt_create
|
||||
FROM
|
||||
sys_file_client
|
||||
WHERE
|
||||
is_delete = 0
|
||||
<if test="status != null and status != ''">
|
||||
AND
|
||||
status = #{status}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
</mapper>
|
253
module-file/src/main/resources/templates/file-client/list.html
Normal file
253
module-file/src/main/resources/templates/file-client/list.html
Normal file
@ -0,0 +1,253 @@
|
||||
<!doctype html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'} ">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
<link rel="stylesheet" type="text/css" href="assets/js/vendor/viewer/viewer.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid layui-anim layui-anim-fadein">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-md12">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body" id="cardBody">
|
||||
<div class="test-table-reload-btn" style="margin-bottom: 10px;">
|
||||
<div class="layui-inline">
|
||||
<input type="text" id="keywords" class="layui-input search-item" placeholder="输入关键字">
|
||||
</div>
|
||||
<button type="button" id="search" class="layui-btn layui-btn-sm">
|
||||
<i class="fa fa-lg fa-search"></i> 搜索
|
||||
</button>
|
||||
</div>
|
||||
<table class="layui-hide" id="dataTable" lay-filter="dataTable"></table>
|
||||
<!-- 表头按钮组 -->
|
||||
<script type="text/html" id="headerToolBar">
|
||||
<div class="layui-btn-group">
|
||||
<button type="button" class="layui-btn layui-btn-sm" lay-event="saveEvent">
|
||||
<i class="fa fa-lg fa-plus"></i> 新增
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" lay-event="updateEvent">
|
||||
<i class="fa fa-lg fa-edit"></i> 编辑
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn-danger layui-btn-sm" lay-event="removeEvent">
|
||||
<i class="fa fa-lg fa-trash"></i> 删除
|
||||
</button>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script type="text/javascript">
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/'
|
||||
}).extend({
|
||||
index: 'lib/index'
|
||||
}).use(['index', 'table', 'laydate', 'common'], function() {
|
||||
var $ = layui.$;
|
||||
var $win = $(window);
|
||||
var table = layui.table;
|
||||
var admin = layui.admin;
|
||||
var laydate = layui.laydate;
|
||||
var common = layui.common;
|
||||
var resizeTimeout = null;
|
||||
var tableUrl = 'api/file-client/listpage';
|
||||
|
||||
// 初始化表格
|
||||
function initTable() {
|
||||
table.render({
|
||||
elem: '#dataTable',
|
||||
id: 'dataTable',
|
||||
url: top.restAjax.path(tableUrl, []),
|
||||
width: admin.screen() > 1 ? '100%' : '',
|
||||
height: $win.height() - 90,
|
||||
limit: 20,
|
||||
limits: [20, 40, 60, 80, 100, 200],
|
||||
toolbar: '#headerToolBar',
|
||||
request: {
|
||||
pageName: 'page',
|
||||
limitName: 'rows'
|
||||
},
|
||||
cols: [
|
||||
[
|
||||
{type:'checkbox', fixed: 'left'},
|
||||
{field: 'rowNum', width: 80, title: '序号', fixed: 'left', align: 'center', templet: '<span>{{d.LAY_INDEX}}</span>'},
|
||||
{field: 'title', width: 200, title: '标题', align: 'center',
|
||||
templet: function (row) {
|
||||
var rowData = row[this.field];
|
||||
if (typeof (rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
return '-';
|
||||
}
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
{field: 'accessKey', width: 180, title: 'Key', align: 'center',
|
||||
templet: function (row) {
|
||||
var rowData = row[this.field];
|
||||
if (typeof (rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
return '-';
|
||||
}
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
{field: 'accessSecret', width: 180, title: 'Secret', align: 'center',
|
||||
templet: function (row) {
|
||||
var rowData = row[this.field];
|
||||
if (typeof (rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
return '-';
|
||||
}
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
{field: 'status', width: 100, title: '状态', align: 'center',
|
||||
templet: function (row) {
|
||||
var rowData = row[this.field];
|
||||
if (typeof (rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
return '-';
|
||||
}
|
||||
if(rowData === 'active') {
|
||||
return '已激活';
|
||||
}
|
||||
if(rowData === 'inactive') {
|
||||
return '未激活';
|
||||
}
|
||||
return '错误';
|
||||
}
|
||||
},
|
||||
{field: 'gmtCreate', width: 180, title: '创建时间', align: 'center',
|
||||
templet: function (row) {
|
||||
var rowData = row[this.field];
|
||||
if (typeof (rowData) === 'undefined' || rowData == null || rowData == '') {
|
||||
return '-';
|
||||
}
|
||||
return rowData;
|
||||
}
|
||||
},
|
||||
]
|
||||
],
|
||||
page: true,
|
||||
parseData: function (data) {
|
||||
return {
|
||||
'code': 0,
|
||||
'msg': '',
|
||||
'count': data.total,
|
||||
'data': data.rows
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 重载表格
|
||||
function reloadTable(currentPage) {
|
||||
table.reload('dataTable', {
|
||||
url: top.restAjax.path(tableUrl, []),
|
||||
where: {
|
||||
keywords: $('#keywords').val(),
|
||||
startTime: $('#startTime').val(),
|
||||
endTime: $('#endTime').val()
|
||||
},
|
||||
page: {
|
||||
curr: currentPage
|
||||
},
|
||||
height: $win.height() - 90,
|
||||
});
|
||||
}
|
||||
|
||||
initTable();
|
||||
|
||||
// 事件 - 页面变化
|
||||
$win.on('resize', function () {
|
||||
clearTimeout(resizeTimeout);
|
||||
resizeTimeout = setTimeout(function () {
|
||||
reloadTable();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
// 删除
|
||||
function removeData(ids) {
|
||||
top.dialog.msg(top.dataMessage.delete, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function (index) {
|
||||
top.dialog.close(index);
|
||||
var layIndex;
|
||||
top.restAjax.delete(top.restAjax.path('api/file-remote/remove/{ids}', [ids]), {}, null, function (code, data) {
|
||||
top.dialog.msg(top.dataMessage.deleteSuccess, {time: 1000});
|
||||
reloadTable();
|
||||
}, function (code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function () {
|
||||
layIndex = top.dialog.msg(top.dataMessage.deleting, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function () {
|
||||
top.dialog.close(layIndex);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 事件 - 增删改
|
||||
table.on('toolbar(dataTable)', function(obj) {
|
||||
var layEvent = obj.event;
|
||||
var checkStatus = table.checkStatus('dataTable');
|
||||
var checkDatas = checkStatus.data;
|
||||
if(layEvent === 'saveEvent') {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: false,
|
||||
closeBtn: 0,
|
||||
area: ['100%', '100%'],
|
||||
shadeClose: true,
|
||||
anim: 2,
|
||||
content: top.restAjax.path('route/file-remote/save', []),
|
||||
end: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
} else if(layEvent === 'updateEvent') {
|
||||
if(checkDatas.length === 0) {
|
||||
top.dialog.msg(top.dataMessage.table.selectEdit);
|
||||
} else if(checkDatas.length > 1) {
|
||||
top.dialog.msg(top.dataMessage.table.selectOneEdit);
|
||||
} else {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: false,
|
||||
closeBtn: 0,
|
||||
area: ['100%', '100%'],
|
||||
shadeClose: true,
|
||||
anim: 2,
|
||||
content: top.restAjax.path('route/file-remote/update?fileRemoteId={fileRemoteId}', [checkDatas[0].fileRemoteId]),
|
||||
end: function() {
|
||||
reloadTable();
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if(layEvent === 'removeEvent') {
|
||||
if(checkDatas.length === 0) {
|
||||
top.dialog.msg(top.dataMessage.table.selectDelete);
|
||||
} else {
|
||||
var ids = '';
|
||||
for(var i = 0, item; item = checkDatas[i++];) {
|
||||
if(i > 1) {
|
||||
ids += '_';
|
||||
}
|
||||
ids += item['fileRemoteId'];
|
||||
}
|
||||
removeData(ids);
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
108
module-file/src/main/resources/templates/file-client/save.html
Normal file
108
module-file/src/main/resources/templates/file-client/save.html
Normal file
@ -0,0 +1,108 @@
|
||||
<!doctype html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'} ">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid layui-anim layui-anim-fadein">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
<span class="layui-breadcrumb" lay-filter="breadcrumb" style="visibility: visible;">
|
||||
<a class="close" href="javascript:void(0);">上级列表</a><span lay-separator="">/</span>
|
||||
<a href="javascript:void(0);"><cite>新增内容</cite></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="layui-card-body" style="padding: 15px;">
|
||||
<form class="layui-form layui-form-pane" lay-filter="dataForm">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" id="title" name="title" class="layui-input" value="" placeholder="请输入标题" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item" pane>
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="status" value="active" title="激活" checked>
|
||||
<input type="radio" name="status" value="inactive" title="未激活">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-layout-admin">
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-footer" style="left: 0;">
|
||||
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交新增</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary close">返回上级</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form', 'laydate', 'laytpl'], function(){
|
||||
var $ = layui.$;
|
||||
var form = layui.form;
|
||||
var laytpl = layui.laytpl;
|
||||
var laydate = layui.laydate;
|
||||
|
||||
function closeBox() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
}
|
||||
|
||||
// 初始化内容
|
||||
function initData() {}
|
||||
initData();
|
||||
|
||||
// 提交表单
|
||||
form.on('submit(submitForm)', function(formData) {
|
||||
top.dialog.confirm(top.dataMessage.commit, function(index) {
|
||||
top.dialog.close(index);
|
||||
var loadLayerIndex;
|
||||
top.restAjax.post(top.restAjax.path('api/file-client/save', []), formData.field, null, function(code, data) {
|
||||
var layerIndex = top.dialog.msg(top.dataMessage.commitSuccess, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function(index) {
|
||||
top.dialog.close(index);
|
||||
window.location.reload();
|
||||
},
|
||||
btn2: function() {
|
||||
closeBox();
|
||||
}
|
||||
});
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.close').on('click', function() {
|
||||
closeBox();
|
||||
});
|
||||
|
||||
// 校验
|
||||
form.verify({
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
125
module-file/src/main/resources/templates/file-client/update.html
Normal file
125
module-file/src/main/resources/templates/file-client/update.html
Normal file
@ -0,0 +1,125 @@
|
||||
<!doctype html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<base th:href="${#request.getContextPath() + '/'} ">
|
||||
<meta charset="utf-8">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-fluid layui-anim layui-anim-fadein">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
<span class="layui-breadcrumb" lay-filter="breadcrumb" style="visibility: visible;">
|
||||
<a class="close" href="javascript:void(0);">上级列表</a><span lay-separator="">/</span>
|
||||
<a href="javascript:void(0);"><cite>编辑内容</cite></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="layui-card-body" style="padding: 15px;">
|
||||
<form class="layui-form layui-form-pane" lay-filter="dataForm">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" id="title" name="title" class="layui-input" value="" placeholder="请输入标题" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item" pane>
|
||||
<label class="layui-form-label">状态</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="status" value="active" title="激活" checked>
|
||||
<input type="radio" name="status" value="inactive" title="未激活">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-layout-admin">
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-footer" style="left: 0;">
|
||||
<button type="button" class="layui-btn" lay-submit lay-filter="submitForm">提交编辑</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary close">返回上级</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/layuiadmin/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
base: 'assets/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'form', 'laydate', 'laytpl'], function(){
|
||||
var $ = layui.$;
|
||||
var form = layui.form;
|
||||
var laytpl = layui.laytpl;
|
||||
var laydate = layui.laydate;
|
||||
var fileRemoteId = top.restAjax.params(window.location.href).fileRemoteId;
|
||||
|
||||
function closeBox() {
|
||||
parent.layer.close(parent.layer.getFrameIndex(window.name));
|
||||
}
|
||||
|
||||
// 初始化内容
|
||||
function initData() {
|
||||
var loadLayerIndex;
|
||||
top.restAjax.get(top.restAjax.path('api/file-client/get/{fileRemoteId}', [fileRemoteId]), {}, null, function(code, data) {
|
||||
var dataFormData = {};
|
||||
for(var i in data) {
|
||||
dataFormData[i] = data[i];
|
||||
}
|
||||
form.val('dataForm', dataFormData);
|
||||
form.render(null, 'dataForm');
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
}
|
||||
initData();
|
||||
|
||||
// 提交表单
|
||||
form.on('submit(submitForm)', function(formData) {
|
||||
top.dialog.confirm(top.dataMessage.commit, function(index) {
|
||||
top.dialog.close(index);
|
||||
var loadLayerIndex;
|
||||
top.restAjax.put(top.restAjax.path('api/file-client/update/{fileRemoteId}', [fileRemoteId]), formData.field, null, function(code, data) {
|
||||
var layerIndex = top.dialog.msg(top.dataMessage.updateSuccess, {
|
||||
time: 0,
|
||||
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
|
||||
shade: 0.3,
|
||||
yes: function(index) {
|
||||
top.dialog.close(index);
|
||||
window.location.reload();
|
||||
},
|
||||
btn2: function() {
|
||||
closeBox();
|
||||
}
|
||||
});
|
||||
}, function(code, data) {
|
||||
top.dialog.msg(data.msg);
|
||||
}, function() {
|
||||
loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3});
|
||||
}, function() {
|
||||
top.dialog.close(loadLayerIndex);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.close').on('click', function() {
|
||||
closeBox();
|
||||
});
|
||||
|
||||
// 校验
|
||||
form.verify({
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user