pom.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
server.sh | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-common/src/main/java/com/ycl/dto/media/Media.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-common/src/main/java/com/ycl/dto/media/PictureZoomParameter.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-common/src/main/java/com/ycl/utils/MediaFileUtil.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-platform/src/main/java/com/ycl/controller/FileController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-platform/src/main/resources/application-dev.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-platform/src/main/resources/application-pro.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
pom.xml
@@ -2,6 +2,18 @@ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>16</source> <target>16</target> </configuration> </plugin> </plugins> </build> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> @@ -101,6 +113,13 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.github.tobato/fastdfs-client --> <dependency> <groupId>com.github.tobato</groupId> <artifactId>fastdfs-client</artifactId> <version>1.27.2</version> </dependency> <!--Hutool Java工具包--> <dependency> <groupId>cn.hutool</groupId> server.sh
New file @@ -0,0 +1,95 @@ #!/bin/bash #定义服务数组 serviceArr=(ycl) #当前路径 rootPath=$(pwd) #输入操作方式 read -p "请输入操作方式对应的序号: 1.start 2.stop -> " action echo ---------------------------------------------------------------------------------- #输入操作服务 read -p "请输入需要操作的服务对应的序号,请以空格分隔: 1.ycl -> " servers=$REPLY echo ---------------------------------------------------------------------------------- #判断操作 if [ "$action" -eq 1 ];then read -p "请输入启动环境参数(如不指定,默认为开发环境): dev-开发环境 prod-生产环境 test-本地测试环境 onlinetest-线上测试环境 -> " env echo ---------------------------------------------------------------------------------- if [ -n "$env" ];then envConfig="--spring.profiles.active="${env} fi for i in $servers do if [ $i -gt 1 ];then echo 输入的服务序号过大 elif [ $i -lt 1 ];then echo 输入的服务序号过小 else i=$(($i-1)) echo 正在启动服务 ${serviceArr[$i]} cd $rootPath/${serviceArr[$i]} # java启动参数 $startConfig #-Xms128m 最小堆 #-Xmx256m 最大堆 此值可以设置与-Xms相同,以避免每次垃圾回收完成后JVM重新分配内存 #-Xmn2g 年轻代 #-Xss128k 线程堆大小a #BackManager配置 if [[ $serviceArr[$i] =~ "ycl" ]];then startConfig="-Xms400m -Xmx400m" else startConfig="-Xms400m -Xmx400m" fi echo 在路径 $(pwd) 下 echo 执行 nohup java $startConfig -jar *.jar $envconfig "&" nohup java $startConfig -jar *.jar $envConfig & pid=$(ps -ef|grep -i ${serviceArr[$i]}|grep .jar|grep -v grep|awk '{print $2}') if [ -n "$pid" ];then echo 启动服务 ${serviceArr[$i]} 成功,进程ID为: $pid else echo 启动服务 ${serviceArr[$i]} 失败,执行的命令为: echo nohup java $startConfig -jar *.jar $envconfig & fi echo ---------------------------------------------------------------------------------- fi done elif [ "$action" -eq 2 ];then for i in $servers do if [ $i -gt 1 ];then echo 输入的服务序号过大 elif [ $i -lt 1 ];then echo 输入的服务序号过小 else i=$(($i-1)) pid=$(ps -ef|grep -i ${serviceArr[$i]}|grep .jar|grep -v grep|awk '{print $2}') serverName=$(ps -ef|grep -i ${serviceArr[$i]}|grep .jar|grep -v grep|awk '{print $12}') if [ -n "$pid" ];then echo 关闭服务 ${serviceArr[$i]} 的进程ID为: $pid echo 关闭服务 ${serviceArr[$i]} 的jar包名为: $serverName kill -9 $pid result=$(ps -ef|grep $pid|grep -v grep) if [ -n "$result" ];then echo 关闭服务成功! else echo 关闭服务失败! 查询到的进程为: echo $result echo 请重新尝试! fi else echo 未启动服务 ${serviceArr[$i]} fi echo ---------------------------------------------------------------------------------- fi done else echo 输入的操作方式有误,请重新执行脚本! fi ycl-common/src/main/java/com/ycl/dto/media/Media.java
New file @@ -0,0 +1,20 @@ package com.ycl.dto.media; import lombok.Data; @Data public class Media { private String type;//类型 private String def; //视频默认图片 private String url1; //小 private String url2; //中 private String url3;//大 private String url4; //最大(暂时不使用) private Integer sort;//集合中的排序 } ycl-common/src/main/java/com/ycl/dto/media/PictureZoomParameter.java
New file @@ -0,0 +1,29 @@ package com.ycl.dto.media; import lombok.Data; /** * 图片缩放参数 */ @Data public class PictureZoomParameter { public static final PictureZoomParameter getBoardPar(){ PictureZoomParameter par =new PictureZoomParameter(); par.setWidth1(300); par.setWidth2(600); par.setWidth3(1200); return par; } private Integer width1; private Integer width2; private Integer width3; private Integer width4; } ycl-common/src/main/java/com/ycl/utils/MediaFileUtil.java
New file @@ -0,0 +1,259 @@ package com.ycl.utils; import com.github.tobato.fastdfs.domain.fdfs.StorePath; import com.github.tobato.fastdfs.domain.upload.FastImageFile; import com.github.tobato.fastdfs.service.FastFileStorageClient; import com.ycl.dto.media.PictureZoomParameter; import com.ycl.dto.media.Media; import net.coobird.thumbnailator.Thumbnails; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import javax.annotation.PostConstruct; import java.awt.image.BufferedImage; import java.io.*; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.regex.Pattern; @Component public class MediaFileUtil { private static MediaFileUtil self; @Value("${fdfs.groupName}") private String groupName; @PostConstruct private void init() { self = this; } @Autowired private FastFileStorageClient storageClient; private static final Pattern videoPattern = Pattern.compile("((mp4|flv|avi|rm|rmvb|wmv)(jpg|png|gif|bmp))"); @Value("${cfg.res}") private String rootPath; private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM"); public MediaFileUtil() throws IOException { } public static String uploadImage(InputStream in) throws IOException { return self.storageClient.uploadImage(new FastImageFile(in, in.available(), "jpg", null)).getFullPath(); } public static String uploadImage(File file) throws IOException { FileInputStream in = new FileInputStream(file); return self.storageClient.uploadImage(new FastImageFile(in, in.available(), "jpg", null)).getFullPath(); } /** * 判断文件类型 * * @param fileName * @return */ public Short getType(String fileName) { String ext = fileName.substring(fileName.lastIndexOf(".")).toLowerCase(); if (".jpg".equals(ext) || ".jpeg".equals(ext) || ".png".equals(ext) || ".gif".equals(ext) || ".bmp".equals(ext)) { return 1; } else if (".mp4".equals(ext) || ".avi".equals(ext) || ".flv".equals(ext) || ".rm".equals(ext) || ".wmv".equals(ext)) { return 2; } else { return 0; } } public Media save(MultipartFile file, PictureZoomParameter zoomPar) throws Exception { String[] fs = file.getOriginalFilename().split("\\."); String ext = fs[fs.length - 1]; switch (this.getType(file.getOriginalFilename())) { case 1: return this.savePicture(file, ext, zoomPar); case 2: return this.saveVideo(file, ext); default: return new Media(); } } public Media savePicture(MultipartFile file, String ext, PictureZoomParameter zoomPar) throws Exception { ByteArrayOutputStream outs = new ByteArrayOutputStream(); Media media = new Media(); media.setType(ext); String path = null; if (zoomPar.getWidth1() != null && zoomPar.getWidth1() > 0) { path = this.thumbAndStorageOfFile(file, ext, zoomPar.getWidth1()); media.setUrl1(path); } if (zoomPar.getWidth2() != null && zoomPar.getWidth2() > 0) { path = this.thumbAndStorageOfFile(file, ext, zoomPar.getWidth2()); media.setUrl2(path); } if (zoomPar.getWidth3() != null && zoomPar.getWidth3() > 0) { path = this.thumbAndStorageOfFile(file, ext, zoomPar.getWidth3()); media.setUrl3(path); } // width4为原图 path = this.thumbAndStorageOfFile(file, ext, zoomPar.getWidth4()); media.setUrl4(path); return media; } /** * 保存视频文件 * * @param file * @param ext * @return * @throws Exception */ public Media saveVideo(MultipartFile file, String ext) throws Exception { // StorePath sp = storageClient.uploadFile(file.getInputStream(), file.getSize(), ext, null); StorePath sp = storageClient.uploadFile(groupName, file.getInputStream(), file.getSize(), ext); Media media = new Media(); media.setType(ext); media.setUrl1(sp.getFullPath()); return media; } /** * 删除一个文件 * * @param rootPath */ public void removeFile(String rootPath) { storageClient.deleteFile(rootPath); } public void removeMedia(Media media) { if (!StringUtils.isEmpty(media.getUrl1())) { storageClient.deleteFile(media.getUrl1()); } if (!StringUtils.isEmpty(media.getUrl2())) { storageClient.deleteFile(media.getUrl2()); } if (!StringUtils.isEmpty(media.getUrl3())) { storageClient.deleteFile(media.getUrl3()); } if (!StringUtils.isEmpty(media.getUrl4())) { storageClient.deleteFile(media.getUrl4()); } } public void removeMedias(List<Media> medias) { if (medias != null) { for (Media m : medias) { if (!StringUtils.isEmpty(m.getUrl1())) { storageClient.deleteFile(m.getUrl1()); } if (!StringUtils.isEmpty(m.getUrl2())) { storageClient.deleteFile(m.getUrl2()); } if (!StringUtils.isEmpty(m.getUrl3())) { storageClient.deleteFile(m.getUrl3()); } if (!StringUtils.isEmpty(m.getUrl4())) { storageClient.deleteFile(m.getUrl4()); } } } } /** * 判断文件是否存在 * * @param url * @return */ public Boolean isEmpty(String url) { return true; } /** * 缩放并且上传 * * @param in * @param ext * @param width * @return * @throws Exception */ private String thumbAndStorage(InputStream in, String ext, Integer width) throws Exception { Thumbnails.Builder fileBuilder = Thumbnails.of(in).scale(1.0).outputQuality(1.0); BufferedImage src = fileBuilder.asBufferedImage(); Integer w = src.getWidth(null); Integer destWidth = width > w ? w : width; ByteArrayOutputStream bouts = new ByteArrayOutputStream(); Thumbnails.of(in).width(destWidth).toOutputStream(bouts); InputStream ins = this.out2In(bouts); StorePath sp = storageClient.uploadFile(groupName, ins, bouts.size(), ext); // StorePath sp = storageClient.uploadFile(ins, bouts.size(), ext, null); bouts.close(); ins.close(); return sp.getFullPath(); } private String thumbAndStorageOfFile(MultipartFile file, String ext, Integer width) throws Exception { Thumbnails.Builder fileBuilder = Thumbnails.of(file.getInputStream()).scale(1.0).outputQuality(1.0); BufferedImage src = fileBuilder.asBufferedImage(); Integer w = src.getWidth(null); Integer destWidth = width == null || width > w ? w : width; ByteArrayOutputStream bouts = new ByteArrayOutputStream(); Thumbnails.of(file.getInputStream()).width(destWidth).toOutputStream(bouts); InputStream ins = this.out2In(bouts); StorePath sp = storageClient.uploadFile(groupName, ins, bouts.size(), ext); // StorePath sp = storageClient.uploadFile(ins, bouts.size(), ext, null); bouts.close(); ins.close(); return sp.getFullPath(); } /** * 输出流转输入流 * * @param outs * @return * @throws Exception */ private InputStream out2In(ByteArrayOutputStream outs) throws Exception { InputStream ins = new ByteArrayInputStream(outs.toByteArray()); return ins; } } ycl-platform/src/main/java/com/ycl/controller/FileController.java
New file @@ -0,0 +1,53 @@ package com.ycl.controller; import com.ycl.api.CommonResult; import com.ycl.dto.media.Media; import com.ycl.dto.media.PictureZoomParameter; import com.ycl.utils.MediaFileUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @RestController @Api(tags = "文件上传") @RequestMapping("/file") public class FileController { @Autowired private MediaFileUtil mediaFileUtil; /** * 上传图片 * * @param file * @return */ @ApiOperation("上传图片") @RequestMapping(value = "/medias", method = RequestMethod.POST) public CommonResult<Media> mediaUpload(@RequestParam("file") MultipartFile file) { try { PictureZoomParameter zoomPar = PictureZoomParameter.getBoardPar(); Media res = mediaFileUtil.save(file, zoomPar); return CommonResult.success(res, "ok"); } catch (Exception e) { return CommonResult.failed("fail!"); } } @ApiOperation("删除图片") @RequestMapping(value = "media/delete", method = RequestMethod.DELETE) public CommonResult<Boolean> delete(@RequestBody Media media) { try { mediaFileUtil.removeMedia(media); return CommonResult.success(true, "ok"); } catch (Exception e) { return CommonResult.failed("fail!"); } } } ycl-platform/src/main/resources/application-dev.yml
@@ -1,10 +1,25 @@ server: port: 8081 port: 8082 tomcat: uri-encoding: UTF-8 servlet: context-path: /sccg compression: true fdfs: groupName: sczhzf soTimeout: 1500 connectTimeout: 600 trackerList: #TrackerList参数,支持多个 - 140.143.152.226:22122 cfg: res: d://resources media-res: 140.143.152.226/media/ snow-flake: datacenterId: 1 machineId: 1 spring: redis: database: 0 ycl-platform/src/main/resources/application-pro.yml
@@ -5,6 +5,21 @@ servlet: context-path: /sccg compression: true fdfs: groupName: sczhzf soTimeout: 1500 connectTimeout: 600 trackerList: #TrackerList参数,支持多个 - 140.143.152.226:22122 - cfg: res: d://resources media-res: 140.143.152.226/media/ snow-flake: datacenterId: 1 machineId: 1 spring: redis: database: 0