diff --git a/bnyer-services/bnyer-file/pom.xml b/bnyer-services/bnyer-file/pom.xml index a6296b8..4ee76a5 100644 --- a/bnyer-services/bnyer-file/pom.xml +++ b/bnyer-services/bnyer-file/pom.xml @@ -16,50 +16,50 @@ - + com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery - + com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config - + com.alibaba.cloud spring-cloud-starter-alibaba-sentinel - + org.springframework.boot spring-boot-starter-actuator - + com.github.tobato fastdfs-client - + io.minio minio ${minio.version} - + com.dimensionalnode bnyer-api-system - + com.dimensionalnode @@ -78,7 +78,22 @@ springfox-swagger-ui ${swagger.fox.version} - + + com.qiniu + qiniu-java-sdk + + + com.squareup.okhttp3 + okhttp + 3.3.0 + + + + org.springframework + spring-mock + 2.0.8 + + @@ -97,5 +112,5 @@ - - \ No newline at end of file + + diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/config/ImgConfig.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/config/ImgConfig.java new file mode 100644 index 0000000..e49c95c --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/config/ImgConfig.java @@ -0,0 +1,25 @@ +package com.bnyer.file.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * @Author: chengkun + * @Date: 2022-06-12-16:24 + * @Description: + */ +@Configuration +@RefreshScope +@Getter +@Setter +public class ImgConfig { + + @Value("${img.fileSize}") + private String fileSize; + + @Value("${img.accuracy}") + private String accuracy; +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/config/QiniuConfig.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/config/QiniuConfig.java new file mode 100644 index 0000000..f7104fa --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/config/QiniuConfig.java @@ -0,0 +1,32 @@ +package com.bnyer.file.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +@Configuration +@RefreshScope +@Getter +@Setter +public class QiniuConfig { + + @Value("${qiniu.accessKey}") + private String accessKey; + + @Value("${qiniu.secretKey}") + private String secretKey; + + @Value("${qiniu.bucketName}") + private String bucketName; + + @Value("${qiniu.url}") + private String url; + + @Value("${qiniu.qiniuHostUrl}") + private String qiniuHostUrl; + + @Value("${qiniu.qiniuCheckImgUrl}") + private String qiniuCheckImgUrl; +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/config/TikTokConfig.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/config/TikTokConfig.java new file mode 100644 index 0000000..147a993 --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/config/TikTokConfig.java @@ -0,0 +1,33 @@ +package com.bnyer.file.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * @Author: qyh + * @Date: 2022-06-12-16:24 + * @Description: + */ +@Configuration +@RefreshScope +@Getter +@Setter +public class TikTokConfig { + @Value("${tiktok.appId}") + private String appId; + + @Value("${tiktok.secret}") + private String secret; + + @Value("${tiktok.grant_type}") + private String grantType; + + @Value("${tiktok.tokenUrl}") + private String tokenUrl; + + @Value("${tiktok.checkImgUrl}") + private String checkImgUrl; +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/controller/SysFileController.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/controller/SysFileController.java index efaf070..f15f167 100644 --- a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/controller/SysFileController.java +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/controller/SysFileController.java @@ -1,7 +1,14 @@ package com.bnyer.file.controller; import com.bnyer.common.core.domain.R; +import com.bnyer.file.config.ImgConfig; +import com.bnyer.file.service.IFileService; +import com.bnyer.file.service.IQiniuService; import com.bnyer.file.service.MinioService; +import com.bnyer.file.utils.ImgUtil; +import com.bnyer.file.vo.ChekFileVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; @@ -10,7 +17,7 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -19,66 +26,86 @@ import java.util.List; * * @author ruoyi */ +@Api(value = "文件上传接口",tags = "文件上传接口") @RestController @Slf4j -public class SysFileController -{ +public class SysFileController { @Autowired private MinioService minioService; + @Autowired + private IQiniuService qiniuService; + @Autowired + private IFileService fileService; + @Autowired + private ImgConfig imgConfig; /** * 批量上传图片 */ + @ApiOperation(value="批量上传到七牛云") @PostMapping("/uploadBatch") - public R> uploadBatch(MultipartFile[] files) - { - try - { + public R> uploadBatch(MultipartFile[] files) { + try { List list = new ArrayList<>(); for (MultipartFile file : files) { - String url = minioService.uploadFile(file); + String url = qiniuService.userUpload(file); list.add(url); } // 上传并返回访问地址 return R.ok(list); - } - catch (Exception e) - { + } catch (Exception e) { log.error("上传文件失败", e); return R.fail("上传文件失败"); } } - @PostMapping("/upload") - @ResponseBody - public R upload(@RequestParam("file") MultipartFile file) { - String url = null; - try{ - url = minioService.uploadFile(file); - }catch (Exception e){ - log.error("文件上传失败,原因为:【{}】",e.getMessage()); - return R.fail("文件上传失败!"); + /** + * 批量上传压缩图片 + * @param files + * @return + * @throws IOException + */ + @ApiOperation(value="批量压缩上传到七牛云") + @PostMapping("/uploadBatchCompImg") + public R> compression(MultipartFile[] files) throws IOException { + List list = new ArrayList<>(); + for (MultipartFile file : files) { + MultipartFile file1 = ImgUtil.commpressPicCycle(Long.parseLong(imgConfig.getFileSize()), Double.parseDouble(imgConfig.getAccuracy()), file); + String url = qiniuService.userUpload(file1); + list.add(url); } - return R.ok(url); - } - @PostMapping("/download") - @ResponseBody - public R download(@RequestParam("fileName") String fileName, HttpServletResponse response) { - minioService.download(fileName,response); - return R.ok(); + // 上传并返回访问地址 + return R.ok(list); } + /** + * 批量审核 + */ + @ApiOperation(value="批量图片审核") + @PostMapping("/checkBatch") + public R> checkBatch(ArrayList files) { + try { + ArrayList list = fileService.checkImg(files); + // 上传并返回访问地址 + return R.ok(list); + } catch (Exception e) { + log.error("上传文件失败", e); + return R.fail("上传文件失败"); + } + } + @ApiOperation(value="批量上传到minio") @PostMapping("/uploadBanner") @ResponseBody public R uploadBanner(@RequestParam("file") MultipartFile file) { String url = null; - try{ + try { url = minioService.uploadBanner(file); - }catch (Exception e){ - log.error("文件上传失败,原因为:【{}】",e.getMessage()); + } catch (Exception e) { + log.error("文件上传失败,原因为:【{}】", e.getMessage()); return R.fail("banner上传失败!"); } return R.ok(url); } + } diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/IFileService.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/IFileService.java new file mode 100644 index 0000000..e11f7cc --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/IFileService.java @@ -0,0 +1,15 @@ +package com.bnyer.file.service; + +import com.bnyer.file.vo.ChekFileVo; +import org.springframework.web.multipart.MultipartFile; + +import java.util.ArrayList; + +/** + * @Author: qyh + * @Date: 2022-06-16-11:03 + * @Description: + */ +public interface IFileService { + ArrayList checkImg(ArrayList multipartFiles); +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/IQiniuService.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/IQiniuService.java new file mode 100644 index 0000000..9c845c7 --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/IQiniuService.java @@ -0,0 +1,23 @@ +package com.bnyer.file.service; + +import org.springframework.web.multipart.MultipartFile; + +import java.util.ArrayList; + +public interface IQiniuService { + String userUpload(MultipartFile file); + + /** + * 检查图片内容是否符合规定 + * @param imageUrl 图片的url地址或者图片Base64编码(Base64编码请求时应在开头加上data:application/octet-stream;base64,) + * @return JSONObject + */ + String checkImageContent(String imageUrl); + + /** + * 检查图片格式 + * @param multipartFiles + * @return + */ + ArrayList checkImageFormat(ArrayList multipartFiles); +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/ITikTokImage.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/ITikTokImage.java new file mode 100644 index 0000000..5a2ea43 --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/ITikTokImage.java @@ -0,0 +1,13 @@ +package com.bnyer.file.service; + +import org.springframework.web.multipart.MultipartFile; + +/** + * @Author: qyh + * @Date: 2022-06-08-18:44 + * @Description: + */ +public interface ITikTokImage { + //抖音图片审核 + Boolean checkImageContent(MultipartFile file); +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioService.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioService.java index e6f2edb..9a7b498 100644 --- a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioService.java +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioService.java @@ -39,10 +39,4 @@ public interface MinioService { */ String uploadFileByThumb(MultipartFile file) throws Exception; - /** - * 下载图片 - * @param fileName 文件名 - * @param response 响应 - */ - void download(String fileName, HttpServletResponse response); } diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioSysFileServiceImpl.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioSysFileServiceImpl.java index f3e22f0..84fd167 100644 --- a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioSysFileServiceImpl.java +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/MinioSysFileServiceImpl.java @@ -88,21 +88,4 @@ public class MinioSysFileServiceImpl implements MinioService client.putObject(args); return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + multipartFile.getName(); } - - @Override - public void download(String fileName, HttpServletResponse response) { - // 获取对象的元数据 - try{ - ObjectStat stat = client.statObject(minioConfig.getBucketName(), fileName); - response.setContentType(stat.contentType()); - response.setCharacterEncoding("UTF-8"); - response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); - InputStream is = client.getObject(minioConfig.getBucketName(), fileName); - IOUtils.copy(is, response.getOutputStream()); - is.close(); - }catch (Exception e){ - log.error("文件下载失败!原因为:",e); - e.printStackTrace(); - } - } } diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/FileServiceImpl.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/FileServiceImpl.java new file mode 100644 index 0000000..67a10a9 --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/FileServiceImpl.java @@ -0,0 +1,63 @@ +package com.bnyer.file.service.impl; + +import com.bnyer.file.service.IFileService; +import com.bnyer.file.service.IQiniuService; +import com.bnyer.file.service.ITikTokImage; +import com.bnyer.file.utils.ImgUtil; +import com.bnyer.file.vo.ChekFileVo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.ArrayList; + +/** + * @Author: Yeman + * @Date: 2022-06-08-10:51 + * @Description: + */ +@Service("file") +public class FileServiceImpl implements IFileService { + @Autowired + private IQiniuService qiniuService; + @Autowired + private ITikTokImage tikTokImage; + @Override + public ArrayList checkImg(ArrayList multipartFiles) { + ArrayList chekFileVos = new ArrayList<>(); + //返回通过校验的数组 + ArrayList multipartFileList = qiniuService.checkImageFormat(multipartFiles); + for (MultipartFile multipartFile : multipartFileList) { + ChekFileVo chekFileVo = new ChekFileVo(); + String filename = multipartFile.getResource().getFilename(); + chekFileVo.setFileName(filename); + String imageString = ImgUtil.getImageString(multipartFile); + String checkMsg = qiniuService.checkImageContent("data:application/octet-stream;base64," +imageString); + if (checkMsg.equals("pass")){ + //抖音图片检测二次检测 + if (tikTokImage.checkImageContent(multipartFile)) { + //可以通过 + chekFileVo.setStatus("1"); + chekFileVos.add(chekFileVo); + }else { + //不可以通过 + chekFileVo.setStatus("2"); + chekFileVos.add(chekFileVo); + } + continue; + } + if (checkMsg.equals("review")){ + //人工审核 + chekFileVo.setStatus("0"); + chekFileVos.add(chekFileVo); + continue; + } + if (checkMsg.equals("block")){ + //不可通过 + chekFileVo.setStatus("2"); + chekFileVos.add(chekFileVo); + } + } + return chekFileVos; + } +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/QiniuServiceImpl.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/QiniuServiceImpl.java new file mode 100644 index 0000000..9425da0 --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/QiniuServiceImpl.java @@ -0,0 +1,193 @@ +package com.bnyer.file.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.bnyer.file.config.QiniuConfig; +import com.bnyer.file.service.IQiniuService; +import com.bnyer.file.utils.StringUtil; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.qiniu.common.QiniuException; +import com.qiniu.common.Zone; +import com.qiniu.http.Client; +import com.qiniu.http.Response; +import com.qiniu.storage.Configuration; +import com.qiniu.storage.UploadManager; +import com.qiniu.storage.model.DefaultPutRet; +import com.qiniu.util.Auth; +import com.qiniu.util.StringMap; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; + +/** + * @Author: Yeman + * @Date: 2022-06-08-10:51 + * @Description: + */ +@Service +public class QiniuServiceImpl implements IQiniuService { + + @Autowired + private QiniuConfig qiniuConfig; + private Zone zone = new Zone.Builder(Zone.autoZone()) + .upHttp("http://upload.qiniup.com") + .upHttps("http://upload.qiniup.com") + .upBackupHttp("http://upload.qiniup.com") + .upBackupHttps("http://upload.qiniup.com") + .rsHttp("http://rs.qiniu.com") + .rsfHttp("http://rsf.qiniu.com") + .apiHttp("http://api.qiniu.com") + .iovipHttp("http://iovip.qbox.me").build(); + @Override + public String userUpload(MultipartFile file) { + return this.updloadFile(file); + } + public String updloadFile(MultipartFile file){ + String url = null; + // 获取文件的名称 + String fileName = file.getOriginalFilename(); + //构造一个带指定 Region 对象的配置类 + Configuration cfg = new Configuration(zone); + cfg.useHttpsDomains=false; + UploadManager uploadManager = new UploadManager(cfg); + Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey()); + String token = auth.uploadToken(qiniuConfig.getBucketName()); + // 使用工具类根据上传文件生成唯一图片名称 + String imgName = StringUtil.getRandomImgName(fileName); + if (!file.isEmpty()) { + InputStream inputStream =null; + try { + inputStream=(InputStream) file.getInputStream(); + Response response = uploadManager.put(inputStream, imgName, token,null,null); + DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); + url=qiniuConfig.getUrl()+"/"+putRet.key; + //System.out.println(putRet.hash); + inputStream.close(); + } catch (QiniuException ex) { + ex.printStackTrace(); + return "error"; + } catch (JsonSyntaxException e) { + e.printStackTrace(); + return "error"; + }catch (IOException ioe){ + ioe.printStackTrace(); + return "error"; + } + return url; + } + return "error"; + } + + + @Override + public String checkImageContent(String imageUrl) { + //基础参数拼接 + String url = qiniuConfig.getQiniuCheckImgUrl(); + String host = qiniuConfig.getQiniuHostUrl(); + String body = "{ \"data\": { \"uri\": \""+imageUrl+"\" }, \"params\": { \"scenes\": [ \"pulp\", \"terror\", \"politician\" ] } }"; + String contentType = "application/json"; + String method = "POST"; + String accessKey= qiniuConfig.getAccessKey(); + String secretKey= qiniuConfig.getSecretKey(); + Auth auth = Auth.create(accessKey, secretKey); + String qiniuToken = "Qiniu " + auth.signRequestV2(url, method, body.getBytes(), contentType); + //头部部分 + StringMap header = new StringMap(); + header.put("Host",host); + header.put("Authorization",qiniuToken); + header.put("Content-Type", contentType); + Configuration c = new Configuration(zone); + Client client = new Client(c); + try { + Response response = client.post(url, body.getBytes(), header, contentType); + JSONObject checkResult = JSON.parseObject(response.bodyString()); + return JSON.parseObject(checkResult.get("result").toString()).get("suggestion").toString(); + } catch (QiniuException e) { + e.printStackTrace(); + } + return null; + } + + + /** + * 检查图片的格式 + * @param multipartFiles + * @return 格式正确的文件 + */ + @Override + public ArrayList checkImageFormat(ArrayList multipartFiles){ + ArrayList afterCheckFiles = new ArrayList<>(); + for (MultipartFile multipartFile : multipartFiles) { + ArrayList imageSuffixList = new ArrayList<>(); + String suffix = getSuffix(multipartFile); + //图片后缀 + imageSuffixList.add("jpg"); + imageSuffixList.add("png"); + imageSuffixList.add("avi"); + imageSuffixList.add("flv"); + imageSuffixList.add("mpg"); + imageSuffixList.add("mpeg"); + imageSuffixList.add("mpe"); + imageSuffixList.add("m1v"); + imageSuffixList.add("m2v"); + imageSuffixList.add("mpv2"); + imageSuffixList.add("mp2v"); + imageSuffixList.add("dat"); + imageSuffixList.add("ts"); + imageSuffixList.add("tp"); + imageSuffixList.add("tpr"); + imageSuffixList.add("pva"); + imageSuffixList.add("pss"); + imageSuffixList.add("mp4"); + imageSuffixList.add("m4v"); + imageSuffixList.add("m4p"); + imageSuffixList.add("m4b"); + imageSuffixList.add("3gp"); + imageSuffixList.add("3gpp"); + imageSuffixList.add("3g2"); + imageSuffixList.add("3gp2"); + imageSuffixList.add("ogg"); + imageSuffixList.add("mov"); + imageSuffixList.add("qt"); + imageSuffixList.add("amr"); + imageSuffixList.add("rm"); + imageSuffixList.add("ram"); + imageSuffixList.add("rmvb"); + imageSuffixList.add("rpm"); + //判断视频的后缀 MP4、MOV、WMV + ArrayList videoSuffixList = new ArrayList<>(); + videoSuffixList.add("mp4"); + videoSuffixList.add("mov"); + videoSuffixList.add("wmv"); + if (suffix != null&&imageSuffixList.contains(suffix)&&multipartFile.getSize() / 1024 < 50000&&multipartFile.getSize() / 1024 > 0) { + afterCheckFiles.add(multipartFile); + } + } + return afterCheckFiles; + } + + public static String getSuffix(MultipartFile file) { + String originalFilename = file.getOriginalFilename(); + //System.out.println(originalFilename); + int dot = originalFilename.lastIndexOf('.'); + int fileNameLength = originalFilename.length(); + if ((dot > -1) && (dot < (originalFilename.length()))) { + String suffix = originalFilename.substring(dot + 1, fileNameLength); + return suffix.toLowerCase(); + } + return null; + } + +// public static void main(String[] args) { +// +// String imageString = ImgUtil.getImageString("C:\\Users\\ASUS\\Documents\\WeChat Files\\wxid_vzk0z5ghy6q922\\FileStorage\\File\\2020-09\\20220608134731.png"); +// JSONObject jsonObject = checkImageContent("data:application/octet-stream;base64," + imageString); +// System.out.println(JSON.parseObject(jsonObject.get("result").toString()).get("suggestion").toString()); +// System.out.println(jsonObject); +// } +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/TikTokImageServiceImpl.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/TikTokImageServiceImpl.java new file mode 100644 index 0000000..7518975 --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/service/impl/TikTokImageServiceImpl.java @@ -0,0 +1,61 @@ +package com.bnyer.file.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bnyer.file.config.TikTokConfig; +import com.bnyer.file.service.ITikTokImage; +import com.bnyer.file.utils.HttpUtils; +import com.bnyer.file.utils.ImgUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.HashMap; + +/** + * @Author: Yeman + * @Date: 2022-06-08-10:51 + * @Description: + */ +@Service("tiktokImage") +public class TikTokImageServiceImpl implements ITikTokImage { + @Autowired + private TikTokConfig tikTokConfig; + + @Override + public Boolean checkImageContent(MultipartFile file) { + String token=""; + HashMap param = new HashMap<>(); + param.put("appId", tikTokConfig.getAppId()); + param.put("secret", tikTokConfig.getSecret()); + param.put("grant_type", tikTokConfig.getGrantType()); + String body = JSON.toJSONString(param); + String res = HttpUtils.sendPost(tikTokConfig.getTokenUrl(), body); + String err_tips = JSON.parseObject(res).get("err_tips").toString(); + if (err_tips.equals("success")){ + res=JSON.parseObject(res).get("data").toString(); + token=JSON.parseObject(res).get("access_token").toString(); + } + if (token!=""){ + HashMap checkParam = new HashMap<>(); + checkParam.put("app_id", tikTokConfig.getAppId()); + checkParam.put("access_token", token); + checkParam.put("image_data", ImgUtil.getImageString(file)); + String checkBody = JSON.toJSONString(checkParam); + String checkRes = HttpUtils.sendPost(tikTokConfig.getCheckImgUrl(), checkBody); + JSONObject jsonObject = JSON.parseObject(checkRes); + JSONArray predicts = JSON.parseArray(jsonObject.get("predicts").toString()); + for (Object predict : predicts) { + String hit = JSON.parseObject(predict.toString()).get("hit").toString(); + if (hit.equals("true")) { + //System.out.println("不通过=========================="); + return false; + } + //System.out.println(predict+"==================="); + } + return true; + } + return false; + } +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/HttpUtils.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/HttpUtils.java new file mode 100644 index 0000000..5aaa297 --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/HttpUtils.java @@ -0,0 +1,77 @@ +package com.bnyer.file.utils; + +import lombok.extern.slf4j.Slf4j; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.URL; +import java.net.URLConnection; + +/** + * @Author: qyh + * @Date: 2022-06-08-18:52 + * @Description: + */ +@Slf4j +public class HttpUtils { + /** + * 向指定 URL 发送POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数 + * @return 所代表远程资源的响应结果 + */ + public static String sendPost(String url, String param) { + PrintWriter out = null; + BufferedReader in = null; + String result = ""; + try { + URL realUrl = new URL(url); + + log.info("post"+url+param); + // 打开和URL之间的连接 + URLConnection conn = realUrl.openConnection(); + // 设置通用的请求属性 + conn.setRequestProperty("content-type", "application/json"); + // 发送POST请求必须设置如下两行 + + conn.setDoOutput(true); + conn.setDoInput(true); + conn.setConnectTimeout(15000); + conn.setReadTimeout(15000); + // 获取URLConnection对象对应的输出流 + out = new PrintWriter(conn.getOutputStream()); + // 发送请求参数 + out.print(param); + // flush输出流的缓冲 + out.flush(); + // 定义BufferedReader输入流来读取URL的响应 + in = new BufferedReader( + new InputStreamReader(conn.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + result += line; + } + } catch (Exception e) { + log.info("发送 POST 请求出现异常!" + e); + e.printStackTrace(); + } + //使用finally块来关闭输出流、输入流 + finally { + try { + if (out != null) { + out.close(); + } + if (in != null) { + in.close(); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + log.info(result); + return result; + } +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/ImgUtil.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/ImgUtil.java index a013890..17e9050 100644 --- a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/ImgUtil.java +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/ImgUtil.java @@ -1,17 +1,22 @@ package com.bnyer.file.utils; +import com.alibaba.nacos.common.codec.Base64; import lombok.extern.slf4j.Slf4j; +import net.coobird.thumbnailator.Thumbnails; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.http.MediaType; +import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.commons.CommonsMultipartFile; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.*; +import java.math.BigDecimal; /** * 图片处理工具类 @@ -130,4 +135,133 @@ public class ImgUtil { } return flag; } + + /** + * 将图片转为base64字符串 + * @param imageFile + * @return + */ + public static String getImageString(String imageFile){ + InputStream is = null; + try { + byte[] data = null; + is = new FileInputStream(new File(imageFile)); + data = new byte[is.available()]; + is.read(data); + return new String(Base64.encodeBase64(data)); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (null != is) { + try { + is.close(); + is = null; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return ""; + } + + /** + * 将图片转为base64字符串 + * @param imageFile + * @return + */ + public static String getImageString(MultipartFile imageFile){ + + InputStream is = null; + try { + byte[] data = null; + byte [] byteArr=imageFile.getBytes(); + is = new ByteArrayInputStream(byteArr); + data = new byte[is.available()]; + is.read(data); + return new String(Base64.encodeBase64(data)); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (null != is) { + try { + is.close(); + is = null; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return ""; + } + + /** + * 功能描述:将文件压缩到指定大小并上传 + * + * + * @Param desFileSize: 指定文件大小(单位为kb) + * @Param accuracy:精度(一般为0.5f) + * @Param mutipartfile:要压缩得图片 + * @return: File + * @auther: qyh + * @date: 2022/7/3 19:17 + */ + public static MultipartFile commpressPicCycle( long desFileSize, double accuracy,MultipartFile mutipartfile) throws IOException{ + String originalFilename = mutipartfile.getOriginalFilename(); + String[] filename = originalFilename.split("\\."); + File fileConver = convertFile(mutipartfile); + long fileSize = FileUtils.sizeOf(fileConver); + InputStream fileInputStream = new FileInputStream(fileConver); + // 判断图片大小是否小于指定图片大小 + if(fileSize <= desFileSize * 1024){ + + return new MockMultipartFile("mutilConver."+filename[1],mutipartfile.getOriginalFilename(),"text/plain",fileInputStream); + } + ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); + byte[] b=new byte[1024]; + int n; + while ((n=fileInputStream.read(b))!=-1){ + bos.write(b,0,n); + } + byte[] bytes = bos.toByteArray(); + //计算宽高 + BufferedImage bim = ImageIO.read(new ByteArrayInputStream(bytes)); + int imgWidth = bim.getWidth(); + int imgHeight = bim.getHeight(); + int desWidth = new BigDecimal(imgWidth).multiply( new BigDecimal(accuracy)).intValue(); + int desHeight = new BigDecimal(imgHeight).multiply( new BigDecimal(accuracy)).intValue(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); //字节输出流(写入到内存) + //Thumbnails.of(new ByteArrayInputStream(bytes)).size(desWidth, desHeight).outputQuality(accuracy).toOutputStream(baos); + Thumbnails.of(fileConver).size(desWidth, desHeight).outputQuality(accuracy).toFile(fileConver); + System.out.println(fileConver.length()+"=========================="); + InputStream inputStream = new FileInputStream(fileConver); + mutipartfile=new MockMultipartFile("mutilConver."+filename[1],mutipartfile.getOriginalFilename(),"text/plain",inputStream); + System.out.println(mutipartfile.getSize()+"====================="); + fileInputStream.close(); + bos.close(); + //如果不满足要求,递归直至满足要求 + return commpressPicCycle(desFileSize,accuracy, mutipartfile); + } + + + /** + * 將MutipartFile轉file + * @param multipartFile + * @return + */ + public static File convertFile(MultipartFile multipartFile) { + File file = null; + try { + String originalFilename = multipartFile.getOriginalFilename(); + String[] filename = originalFilename.split("\\."); + if (filename[0].length()<3){ + filename[0]=filename[0]+"plus"; + } + file = File.createTempFile(filename[0], "."+filename[1]); + multipartFile.transferTo(file); + file.deleteOnExit(); + } catch (IOException e) { + e.printStackTrace(); + } + return file; + } } diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/StringUtil.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/StringUtil.java new file mode 100644 index 0000000..2ffe9bb --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/utils/StringUtil.java @@ -0,0 +1,162 @@ +package com.bnyer.file.utils; + +import cn.hutool.core.date.DateUtil; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @Author: Yeman + * @Date: 2022-06-08-11:08 + * @Description: + */ +@Slf4j +public class StringUtil { + /** + * 数值类型前面补零(共13位) + * @param num + * @return + */ + public static String supplementZeroGenerateThirteen(int num){ + String str = String.format("%013d", num); + + return str; + } + + /** + * 数值类型前面补零(共16位) + * @param num + * @return + */ + public static String supplementZeroGenerateSixteen(int num){ + String str = String.format("%016d", num); + + return str; + } + /** + * 数值类型前面补零(共3位) + * @param num + * @return + */ + public static String supplementZeroGenerateThree(int num){ + String str = String.format("%03d", num); + + return str; + } + + /** + * 判断字符串是不是double型 + * @param str + * @return + */ + public static boolean isNumeric(String str){ + Pattern pattern = Pattern.compile("[0-9]+[.]{0,1}[0-9]*[dD]{0,1}"); + Matcher isNum = pattern.matcher(str); + if( !isNum.matches() ){ + return false; + } + return true; + } + + public static String trim(String str, boolean nullFlag){ + String tempStr = null; + + if (str != null) + { + tempStr = str.trim(); + } + + if (nullFlag) + { + if ("".equals(tempStr) || "null".equals(tempStr)) + { + tempStr = null; + } + } + else + { + if (tempStr == null) + { + tempStr = ""; + } + } + + return tempStr; + } + public static String replace(String strSource, String strFrom, String strTo) { + if(strSource==null){ + return null; + } + int i = 0; + if ((i = strSource.indexOf(strFrom, i)) >= 0) { + char[] cSrc = strSource.toCharArray(); + char[] cTo = strTo.toCharArray(); + int len = strFrom.length(); + StringBuffer buf = new StringBuffer(cSrc.length); + buf.append(cSrc, 0, i).append(cTo); + i += len; + int j = i; + while ((i = strSource.indexOf(strFrom, i)) > 0) { + buf.append(cSrc, j, i - j).append(cTo); + i += len; + j = i; + } + buf.append(cSrc, j, cSrc.length - j); + return buf.toString(); + } + return strSource; + } + + + public static String deal(String str) { + str = replace(str, "\\", "\\\\"); + str = replace(str, "'", "\\'"); + str = replace(str, "\r", "\\r"); + str = replace(str, "\n", "\\n"); + str = replace(str, "\"", "\\\""); + return str; + } + + public static String GetMapToXML(Map param){ + StringBuffer sb = new StringBuffer(); + sb.append(""); + for (Map.Entry entry : param.entrySet()) { + sb.append("<"+ entry.getKey() +">"); + sb.append(entry.getValue()); + sb.append(""); + } + sb.append(""); + return sb.toString(); + } + + public static void main(String[] args){ + //String a = StringUtil.supplementZeroGenerateThirteen(1000); + double a = 32.; + System.out.println(StringUtil.isNumeric("32.")); + System.out.println(a); + } + + /** + * @Description: 生成唯一图片名称 + * @Param: fileName + * @return: 云服务器fileName + */ + public static String getRandomImgName(String fileName) { + + int index = fileName.lastIndexOf("."); + + if ((fileName == null || fileName.isEmpty()) || index == -1){ + throw new IllegalArgumentException(); + } + // 获取文件后缀 + String suffix = fileName.substring(index); + // 生成UUID + String uuid = UUID.randomUUID().toString().replaceAll("-", ""); + // 生成上传至云服务器的路径 + String path = "code/duck/" + DateUtil.today() + "-" + uuid + suffix; + return path; + } +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/vo/ChekFileVo.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/vo/ChekFileVo.java new file mode 100644 index 0000000..12f6e03 --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/vo/ChekFileVo.java @@ -0,0 +1,21 @@ +package com.bnyer.file.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +/** + * @Author qyh + * @Date 2022/7/6 21:16 + * @Description + */ +@Getter +@Setter +@ApiModel("图片检查响应类") +public class ChekFileVo { + @ApiModelProperty(value="状态(0->待审核;1->审核通过;2->审核拒绝)") + private String status; + @ApiModelProperty(value="文件名称") + private String fileName; +} diff --git a/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/vo/TiktokImgVo.java b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/vo/TiktokImgVo.java new file mode 100644 index 0000000..24b32bb --- /dev/null +++ b/bnyer-services/bnyer-file/src/main/java/com/bnyer/file/vo/TiktokImgVo.java @@ -0,0 +1,45 @@ +package com.bnyer.file.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + + +@Getter +@Setter +@ApiModel("抖音图片响应类") +public class TiktokImgVo implements Serializable { + + @ApiModelProperty(value="id") + private Long id; + + @ApiModelProperty(value="图片地址") + private String imgUrl; + + @ApiModelProperty(value="用户id") + private Long creatorId; + + @ApiModelProperty(value="分类id") + private Long typeId; + + @ApiModelProperty(value="下载量") + private Integer downloadNum; + + @ApiModelProperty(value="点赞量") + private Integer greatNum; + + @ApiModelProperty(value="收藏量") + private Integer collectionNum; + + @ApiModelProperty(value="状态(0->待审核;1->审核通过;2->审核拒绝)") + private String status; + + @ApiModelProperty(value="是否热门(0->冷门;1->热门)") + private String isHot; + + private String fileName; + private static final long serialVersionUID = 1L; +} diff --git a/bnyer-services/bnyer-file/src/main/resources/bootstrap.yml b/bnyer-services/bnyer-file/src/main/resources/bootstrap.yml index 1178a47..ccea5fc 100644 --- a/bnyer-services/bnyer-file/src/main/resources/bootstrap.yml +++ b/bnyer-services/bnyer-file/src/main/resources/bootstrap.yml @@ -13,3 +13,6 @@ spring: profiles: # 环境配置 active: dev + servlet: + multipart: + maxFileSize: 5MB diff --git a/bnyer-services/bnyer-img/pom.xml b/bnyer-services/bnyer-img/pom.xml index 970d1b9..1e6c171 100644 --- a/bnyer-services/bnyer-img/pom.xml +++ b/bnyer-services/bnyer-img/pom.xml @@ -115,6 +115,12 @@ alipay-sdk-java + + + com.qiniu + qiniu-java-sdk + 7.2.18 + diff --git a/pom.xml b/pom.xml index 0c1278d..9270980 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,7 @@ 3.16.2 4.23.21.ALL 4.2.0 + 7.2.18 @@ -275,7 +276,12 @@ hutool-all ${hutool.version} - + + + com.qiniu + qiniu-java-sdk + ${qiniu.version} +