From a17d2f31ed32e9b3fee5352fe42d50560ad6a2ee Mon Sep 17 00:00:00 2001 From: yizhaorong <243653385@qq.com> Date: Wed, 10 Jun 2020 22:30:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=AD=98=E5=82=A8=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/yzr/controller/AppController.java | 7 +- .../org/yzr/controller/PackageController.java | 74 ++++++----- src/main/java/org/yzr/model/Package.java | 10 -- src/main/java/org/yzr/model/Storage.java | 9 -- src/main/java/org/yzr/service/AppService.java | 91 +++++++++++++- .../java/org/yzr/service/PackageService.java | 119 +++++++++--------- .../java/org/yzr/service/UserService.java | 2 +- .../java/org/yzr/utils/file/PathManager.java | 17 +++ .../java/org/yzr/utils/image/QRCodeUtil.java | 96 ++++++++++---- .../java/org/yzr/utils/parser/APKParser.java | 7 ++ .../java/org/yzr/utils/parser/IPAParser.java | 10 +- .../yzr/utils/webhook/DingDingWebHook.java | 28 +++-- .../java/org/yzr/utils/webhook/IWebHook.java | 4 +- .../org/yzr/utils/webhook/WebHookClient.java | 8 +- src/main/resources/templates/index.html | 8 +- 15 files changed, 323 insertions(+), 167 deletions(-) diff --git a/src/main/java/org/yzr/controller/AppController.java b/src/main/java/org/yzr/controller/AppController.java index 8870598..ffa2031 100644 --- a/src/main/java/org/yzr/controller/AppController.java +++ b/src/main/java/org/yzr/controller/AppController.java @@ -5,7 +5,10 @@ import org.apache.shiro.authz.annotation.RequiresAuthentication; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; import org.yzr.model.User; import org.yzr.service.AppService; import org.yzr.utils.file.PathManager; @@ -71,7 +74,7 @@ public class AppController { return map; } -// @RequiresPermissions("/app/delete") + @RequiresPermissions("/app/delete") @RequestMapping("/app/delete/{id}") @ResponseBody public BaseResponse deleteById(@PathVariable("id") String id, HttpServletRequest request) { diff --git a/src/main/java/org/yzr/controller/PackageController.java b/src/main/java/org/yzr/controller/PackageController.java index 5c5722e..04db762 100644 --- a/src/main/java/org/yzr/controller/PackageController.java +++ b/src/main/java/org/yzr/controller/PackageController.java @@ -1,12 +1,11 @@ package org.yzr.controller; -import com.alibaba.fastjson.JSON; -import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.subject.Subject; +import org.jetbrains.annotations.NotNull; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -23,8 +22,6 @@ import org.yzr.service.PackageService; import org.yzr.service.StorageService; import org.yzr.service.UserService; import org.yzr.storage.StorageUtil; -import org.yzr.utils.file.FileType; -import org.yzr.utils.file.FileUtil; import org.yzr.utils.file.PathManager; import org.yzr.utils.image.QRCodeUtil; import org.yzr.utils.ipa.PlistGenerator; @@ -37,10 +34,10 @@ import org.yzr.vo.PackageViewModel; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.*; +import java.io.OutputStreamWriter; +import java.io.Writer; import java.util.HashMap; import java.util.Map; -import java.util.UUID; @Controller @@ -113,44 +110,57 @@ public class PackageController { @ResponseBody public BaseResponse upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) { try { - String token = request.getParameter("token"); - User user = this.userService.findByToken(token); - if (user == null) { - Subject currentUser = SecurityUtils.getSubject(); - user = (User) currentUser.getPrincipal(); - } + // 1. 鉴权 + User user = getUser(request); // 无用户信息不允许上传 if (user == null) { return ResponseUtil.unauthz(); } - // 检测文件 + // 2. 检测文件 String filePath = storageUtil.checkAndTransfer(file.getInputStream(), file.getContentType(), file.getOriginalFilename()); if (filePath == null) { return ResponseUtil.fail(401, "不支持的文件类型"); } - // 获取扩展参数 - Map extra = new HashMap<>(); - String jobName = request.getParameter("jobName"); - String buildNumber = request.getParameter("buildNumber"); - if (StringUtils.hasLength(jobName)) { - extra.put("jobName", jobName); - } - if (StringUtils.hasLength(buildNumber)) { - extra.put("buildNumber", buildNumber); - } - Package aPackage = this.packageService.save(filePath, extra, user); -// App app = this.appService.savePackage(aPackage, user); -// // URL -// String codeURL = this.pathManager.getBaseURL(false) + "p/code/" + app.getCurrentPackage().getId(); -// // 发送WebHook消息 -// WebHookClient.sendMessage(app, pathManager); - return ResponseUtil.ok(); + // 3. 解析扩展参数 + Map extra = getExtraParams(request); + // 4. 入库 + App app = this.appService.addPackage(filePath, extra, user); + // 5. 发送通知 + String codeURL = PathManager.request(request).getBaseURL() + "/p/code/" + app.getCurrentPackage().getId(); + // 发送WebHook消息 + WebHookClient.sendMessage(app, PathManager.request(request).getBaseURL(), storageUtil); + return ResponseUtil.ok(codeURL); } catch (Exception e) { e.printStackTrace(); return ResponseUtil.badArgument(); } } + @NotNull + private Map getExtraParams(HttpServletRequest request) { + Map extra = new HashMap<>(); + String jobName = request.getParameter("jobName"); + String buildNumber = request.getParameter("buildNumber"); + if (StringUtils.hasLength(jobName)) { + extra.put("jobName", jobName); + } + if (StringUtils.hasLength(buildNumber)) { + extra.put("buildNumber", buildNumber); + } + return extra; + } + + private User getUser(HttpServletRequest request) { + User user; + String token = request.getParameter("token"); + user = this.userService.findByToken(token); + if (user == null) { + Subject currentUser = SecurityUtils.getSubject(); + user = (User) currentUser.getPrincipal(); + } + return user; + } + /** * 下载文件源文件(ipa 或 apk) * @@ -178,7 +188,7 @@ public class PackageController { } // 文件名称转换 String fileName = aPackage.getName() + "_" + aPackage.getVersion(); - String ext = "." + FilenameUtils.getExtension(aPackage.getFileName()); + String ext = "." + FilenameUtils.getExtension(aPackage.getSourceFile().getKey()); String appName = new String(fileName.getBytes("UTF-8"), "iso-8859-1"); return ResponseEntity.ok().contentType(mediaType).header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + appName + ext + "\"").body(file); @@ -195,7 +205,7 @@ public class PackageController { * @param response */ @RequestMapping("/m/{id}") - public void getManifest(@PathVariable("id") String id, HttpServletRequest request, HttpServletResponse response) { + public void getManifest(@PathVariable("id") String id, HttpServletRequest request, HttpServletResponse response) { try { PackageViewModel viewModel = this.packageService.findById(id, request); if (viewModel != null && viewModel.isiOS()) { diff --git a/src/main/java/org/yzr/model/Package.java b/src/main/java/org/yzr/model/Package.java index 5f3b60d..70e3ce7 100644 --- a/src/main/java/org/yzr/model/Package.java +++ b/src/main/java/org/yzr/model/Package.java @@ -32,8 +32,6 @@ public class Package { private String platform; // 扩展消息 (json格式) private String extra; - // 文件名 - private String fileName; // 源文件 @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name="source_file_id",referencedColumnName="id") @@ -130,14 +128,6 @@ public class Package { this.extra = extra; } - public String getFileName() { - return fileName; - } - - public void setFileName(String fileName) { - this.fileName = fileName; - } - public Storage getSourceFile() { return sourceFile; } diff --git a/src/main/java/org/yzr/model/Storage.java b/src/main/java/org/yzr/model/Storage.java index 2aa2902..d4c390f 100644 --- a/src/main/java/org/yzr/model/Storage.java +++ b/src/main/java/org/yzr/model/Storage.java @@ -22,7 +22,6 @@ public class Storage { private String url; private long createTime; private long updateTime; - private Boolean deleted; public String getId() { return id; @@ -87,12 +86,4 @@ public class Storage { public void setUpdateTime(long updateTime) { this.updateTime = updateTime; } - - public Boolean getDeleted() { - return deleted; - } - - public void setDeleted(Boolean deleted) { - this.deleted = deleted; - } } diff --git a/src/main/java/org/yzr/service/AppService.java b/src/main/java/org/yzr/service/AppService.java index 3e713d8..627c10c 100644 --- a/src/main/java/org/yzr/service/AppService.java +++ b/src/main/java/org/yzr/service/AppService.java @@ -1,6 +1,9 @@ package org.yzr.service; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.yzr.dao.AppDao; @@ -14,14 +17,17 @@ import org.yzr.model.User; import org.yzr.storage.StorageUtil; import org.yzr.utils.CharUtil; import org.yzr.utils.file.PathManager; +import org.yzr.utils.image.ImageUtils; +import org.yzr.utils.parser.ParserClient; import org.yzr.vo.AppViewModel; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.transaction.Transactional; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.*; @Service public class AppService { @@ -74,10 +80,11 @@ public class AppService { if (app != null) { app.getPackageList().forEach(aPackage -> { - try{ + try { aPackage.getSourceFile().getKey(); aPackage.getIconFile().getKey(); - } catch (Exception e) {} + } catch (Exception e) { + } }); AppViewModel appViewModel = new AppViewModel(app, request, true); return appViewModel; @@ -117,7 +124,7 @@ public class AppService { public void deleteById(String id) { App app = this.appDao.findById(id).get(); if (app != null) { - app.getPackageList().forEach(aPackage ->{ + app.getPackageList().forEach(aPackage -> { Storage iconFile = aPackage.getIconFile(); this.storageUtil.delete(iconFile.getKey()); this.storageDao.deleteById(iconFile.getId()); @@ -159,4 +166,76 @@ public class AppService { } return list; } + + @Transactional + public App addPackage(String filePath, Map extra, User user) throws Exception { + // 1. 构建包 + Package aPackage = ParserClient.parse(filePath); + // 2. 文件转存 + storeFiles(filePath, aPackage); + // 获取包对应的APP是否存在 + App app = getApp(user, aPackage); + // 3. 更新包信息 + aPackage.setApp(app); + // 4. 更新包信息 + aPackage = this.packageDao.save(aPackage); + // 5. 更新app信息 + app.setName(aPackage.getName()); + app.getPackageList().add(aPackage); + app.setCurrentPackage(aPackage); + this.appDao.save(app); + return app; + } + + /** + * 获取APP信息 + * @param user + * @param aPackage + * @return + */ + @NotNull + private App getApp(User user, Package aPackage) { + App app = this.appDao.getByBundleIDAndPlatformAndOwner(aPackage.getBundleID(), aPackage.getPlatform(), user); + if (app == null) { + app = new App(); + String shortCode = CharUtil.generate(4); + while (this.appDao.findByShortCode(shortCode) != null) { + shortCode = CharUtil.generate(4); + } + BeanUtils.copyProperties(aPackage, app); + app.setShortCode(shortCode); + // 获取用户信息 + user = this.userDao.findById(user.getId()).get(); + app.setOwner(user); + } else { + // 级联查询 + app.getPackageList().forEach(aPackage1 -> { + }); + app.getWebHookList().forEach(webHook -> { + }); + } + return app; + } + + /** + * 转存文件 + * @param filePath + * @param aPackage + * @throws IOException + */ + private void storeFiles(String filePath, Package aPackage) throws IOException { + // 2.1 源文件 + File sourceFile = new File(filePath); + Storage storage = storageUtil.store(new FileInputStream(sourceFile), sourceFile.length(), "application/octet-stream", sourceFile.getName()); + FileUtils.forceDelete(sourceFile); + aPackage.setSourceFile(storage); + // 2.2 图标文件 + String iconFilePath = PathManager.getTempFilePath("png"); + ImageUtils.resize(aPackage.getIconFile().getUrl(), iconFilePath, 192, 192); + File iconFile = new File(iconFilePath); + Storage iconStorage = storageUtil.store(new FileInputStream(iconFile), iconFile.length(), "application/png", iconFile.getName()); + FileUtils.forceDelete(new File(aPackage.getIconFile().getUrl())); + FileUtils.forceDelete(iconFile); + aPackage.setIconFile(iconStorage); + } } diff --git a/src/main/java/org/yzr/service/PackageService.java b/src/main/java/org/yzr/service/PackageService.java index 0ec53c8..6161081 100644 --- a/src/main/java/org/yzr/service/PackageService.java +++ b/src/main/java/org/yzr/service/PackageService.java @@ -77,65 +77,66 @@ public class PackageService { @Transactional public Package save(String filePath, Map extra, User user) throws Exception { Package aPackage = ParserClient.parse(filePath); - String fileName = aPackage.getPlatform() + "." + FilenameUtils.getExtension(filePath); - // 更新文件名 - aPackage.setFileName(fileName); - // 获取用户信息 - user = this.userDao.findById(user.getId()).get(); - // 设置用户信息 - App app = this.appDao.getByBundleIDAndPlatformAndOwner(aPackage.getBundleID(), aPackage.getPlatform(), user); - if (app == null) { - app = new App(); - String shortCode = CharUtil.generate(4); - while (this.appDao.findByShortCode(shortCode) != null) { - shortCode = CharUtil.generate(4); - } - BeanUtils.copyProperties(aPackage, app); - app.setShortCode(shortCode); - app.setOwner(user); - } else { - // 级联查询 - app.getPackageList().forEach(aPackage1 -> { - }); - app.getWebHookList().forEach(webHook -> {}); - } - aPackage.setApp(app); - String packagePath = PathManager.getFullPath(aPackage); - String tempIconPath = PathManager.getTempIconPath(aPackage); - String sourcePath = packagePath + File.separator + fileName; - // 获取文件后缀 - String ext = FilenameUtils.getExtension(fileName); - // 生成文件名 - String newFileName = UUID.randomUUID().toString() + ".png"; - // 转存到 tmp - String iconPath = FileUtils.getTempDirectoryPath() + File.separator + newFileName; - iconPath = iconPath.replaceAll("//", "/"); - - // 拷贝图标 - ImageUtils.resize(tempIconPath, iconPath, 192, 192); - // 源文件 - FileUtils.copyFile(new File(filePath), new File(sourcePath)); - - // 删除临时图标 - FileUtils.forceDelete(new File(tempIconPath)); - // 源文件 - FileUtils.forceDelete(new File(filePath)); - File sourceFile = new File(sourcePath); - File iconFile = new File(iconPath); - Storage storage = storageUtil.store(new FileInputStream(sourceFile), sourceFile.length(), "application/octet-stream", fileName); - Storage iconStorage = storageUtil.store(new FileInputStream(iconFile), iconFile.length(), "application/x-png", iconFile.getName()); - // 删除临时图标 - FileUtils.forceDelete(sourceFile); - // 源文件 - FileUtils.forceDelete(iconFile); - aPackage.setIconFile(iconStorage); - aPackage.setSourceFile(storage); - aPackage = this.packageDao.save(aPackage); - - app.setName(aPackage.getName()); - app.getPackageList().add(aPackage); - app.setCurrentPackage(aPackage); - this.appDao.save(app); return aPackage; +// String fileName = aPackage.getPlatform() + "." + FilenameUtils.getExtension(filePath); +// // 更新文件名 +// aPackage.setFileName(fileName); +// // 获取用户信息 +// user = this.userDao.findById(user.getId()).get(); +// // 设置用户信息 +// App app = this.appDao.getByBundleIDAndPlatformAndOwner(aPackage.getBundleID(), aPackage.getPlatform(), user); +// if (app == null) { +// app = new App(); +// String shortCode = CharUtil.generate(4); +// while (this.appDao.findByShortCode(shortCode) != null) { +// shortCode = CharUtil.generate(4); +// } +// BeanUtils.copyProperties(aPackage, app); +// app.setShortCode(shortCode); +// app.setOwner(user); +// } else { +// // 级联查询 +// app.getPackageList().forEach(aPackage1 -> { +// }); +// app.getWebHookList().forEach(webHook -> {}); +// } +// aPackage.setApp(app); +// String packagePath = PathManager.getFullPath(aPackage); +// String tempIconPath = PathManager.getTempIconPath(aPackage); +// String sourcePath = packagePath + File.separator + fileName; +// // 获取文件后缀 +// String ext = FilenameUtils.getExtension(fileName); +// // 生成文件名 +// String newFileName = UUID.randomUUID().toString() + ".png"; +// // 转存到 tmp +// String iconPath = FileUtils.getTempDirectoryPath() + File.separator + newFileName; +// iconPath = iconPath.replaceAll("//", "/"); +// +// // 拷贝图标 +// ImageUtils.resize(tempIconPath, iconPath, 192, 192); +// // 源文件 +// FileUtils.copyFile(new File(filePath), new File(sourcePath)); +// +// // 删除临时图标 +// FileUtils.forceDelete(new File(tempIconPath)); +// // 源文件 +// FileUtils.forceDelete(new File(filePath)); +// File sourceFile = new File(sourcePath); +// File iconFile = new File(iconPath); +// Storage storage = storageUtil.store(new FileInputStream(sourceFile), sourceFile.length(), "application/octet-stream", fileName); +// Storage iconStorage = storageUtil.store(new FileInputStream(iconFile), iconFile.length(), "application/x-png", iconFile.getName()); +// // 删除临时图标 +// FileUtils.forceDelete(sourceFile); +// // 源文件 +// FileUtils.forceDelete(iconFile); +// aPackage.setIconFile(iconStorage); +// aPackage.setSourceFile(storage); +// aPackage = this.packageDao.save(aPackage); +// +// app.setName(aPackage.getName()); +// app.getPackageList().add(aPackage); +// app.setCurrentPackage(aPackage); +// this.appDao.save(app); +// return aPackage; } } diff --git a/src/main/java/org/yzr/service/UserService.java b/src/main/java/org/yzr/service/UserService.java index 569cc72..a10e14b 100644 --- a/src/main/java/org/yzr/service/UserService.java +++ b/src/main/java/org/yzr/service/UserService.java @@ -142,7 +142,7 @@ public class UserService { String[] perms = new String[]{ "/apps", "/apps/get", - "/apps/delete", + "/app/delete", "/packageList/get" }; for (String string : perms) { diff --git a/src/main/java/org/yzr/utils/file/PathManager.java b/src/main/java/org/yzr/utils/file/PathManager.java index 21261b9..2570093 100644 --- a/src/main/java/org/yzr/utils/file/PathManager.java +++ b/src/main/java/org/yzr/utils/file/PathManager.java @@ -11,6 +11,7 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.net.InetAddress; +import java.util.UUID; @Component public class PathManager { @@ -55,6 +56,22 @@ public class PathManager { return path.toString(); } + /** + * 获取临时文件路径 + * @param ext 扩展名 + * @return + */ + public static String getTempFilePath(String ext) { + StringBuilder path = new StringBuilder(); + path.append(FileUtils.getTempDirectoryPath()); + // 如果目录不存在,创建目录 + File dir = new File(path.toString()); + if (!dir.exists()) dir.mkdirs(); + path.append(UUID.randomUUID().toString()); + path.append(".").append(ext); + return path.toString(); + } + /** * 获取上传路径 * diff --git a/src/main/java/org/yzr/utils/image/QRCodeUtil.java b/src/main/java/org/yzr/utils/image/QRCodeUtil.java index 228bbcb..ff15867 100644 --- a/src/main/java/org/yzr/utils/image/QRCodeUtil.java +++ b/src/main/java/org/yzr/utils/image/QRCodeUtil.java @@ -7,6 +7,7 @@ import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import org.jetbrains.annotations.NotNull; import javax.imageio.ImageIO; import java.awt.*; @@ -33,6 +34,8 @@ public class QRCodeUtil { private File icon; + private InputStream inputStream; + private String format = "png"; public static QRCodeUtil encode(String text) { @@ -52,12 +55,21 @@ public class QRCodeUtil { return this; } + public QRCodeUtil withIcon(InputStream inputStream) { + this.inputStream = inputStream; + return this; + } + public boolean writeTo(OutputStream outputStream) { try { BitMatrix bitMatrix = getBitMatrix(); if (this.icon != null) { MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF); - BufferedImage bufferedImage = drawIconInMatrix(MatrixToImageWriter.toBufferedImage(bitMatrix,matrixToImageConfig), this.icon); + BufferedImage bufferedImage = drawIconInMatrix(MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig), this.icon); + ImageIO.write(bufferedImage, format, outputStream); + } else if (this.inputStream != null) { + MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF); + BufferedImage bufferedImage = drawIconInMatrix(MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig), this.inputStream); ImageIO.write(bufferedImage, format, outputStream); } else { MatrixToImageWriter.writeToStream(bitMatrix, format, outputStream); @@ -76,9 +88,13 @@ public class QRCodeUtil { BitMatrix bitMatrix = getBitMatrix(); if (this.icon != null) { MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF); - BufferedImage bufferedImage = drawIconInMatrix(MatrixToImageWriter.toBufferedImage(bitMatrix,matrixToImageConfig), this.icon); + BufferedImage bufferedImage = drawIconInMatrix(MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig), this.icon); ImageIO.write(bufferedImage, format, file); - } else { + } else if (this.inputStream != null) { + MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF); + BufferedImage bufferedImage = drawIconInMatrix(MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig), this.inputStream); + ImageIO.write(bufferedImage, format, file); + } else { MatrixToImageWriter.writeToPath(bitMatrix, format, file.toPath()); } return true; @@ -104,10 +120,11 @@ public class QRCodeUtil { /** * 识别指定文件的二维码 + * * @param file * @return */ - public static String parseCode(File file) { + public static String parseCode(File file) { BufferedImage bufferedImage = null; try { bufferedImage = ImageIO.read(file); @@ -119,23 +136,24 @@ public class QRCodeUtil { /** * 识别指定图片的二维码 + * * @param bufferedImage * @return */ - public static String parseCode(BufferedImage bufferedImage) { + public static String parseCode(BufferedImage bufferedImage) { String content = null; try { //读取指定的二维码文件 MultiFormatReader formatReader = new MultiFormatReader(); - BinaryBitmap binaryBitmap= new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage))); + BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage))); //定义二维码参数 - Map hints= new HashMap<>(); + Map hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); Result result = formatReader.decode(binaryBitmap, hints); //输出相关的二维码信息 - System.out.println("解析结果:"+result.toString()); - System.out.println("二维码格式类型:"+result.getBarcodeFormat()); - System.out.println("二维码文本内容:"+result.getText()); + System.out.println("解析结果:" + result.toString()); + System.out.println("二维码格式类型:" + result.getBarcodeFormat()); + System.out.println("二维码文本内容:" + result.getText()); content = result.getText(); if (bufferedImage != null) { bufferedImage.flush(); @@ -148,6 +166,7 @@ public class QRCodeUtil { /** * 识别输入流的二维码 + * * @param inputStream * @return */ @@ -163,11 +182,43 @@ public class QRCodeUtil { /** * 二维码添加logo + * * @param matrixImage 源二维码图片 - * @param logoFile logo图片 + * @param logoFile logo图片 * @return 返回带有logo的二维码图片 */ - private BufferedImage drawIconInMatrix(BufferedImage matrixImage, File logoFile) throws IOException{ + private BufferedImage drawIconInMatrix(BufferedImage matrixImage, File logoFile) throws IOException { + /** + * 读取Logo图片 + */ + BufferedImage logo = ImageIO.read(logoFile); + return getBufferedImage(matrixImage, logo); + } + + /** + * 二维码添加logo + * + * @param matrixImage 源二维码图片 + * @param inputStream logo图片 + * @return 返回带有logo的二维码图片 + */ + private BufferedImage drawIconInMatrix(BufferedImage matrixImage, InputStream inputStream) throws IOException { + /** + * 读取Logo图片 + */ + BufferedImage logo = ImageIO.read(inputStream); + return getBufferedImage(matrixImage, logo); + + } + + /** + * 图片矩阵 + * @param matrixImage + * @param logo + * @return + */ + @NotNull + private BufferedImage getBufferedImage(BufferedImage matrixImage, BufferedImage logo) { /** * 读取二维码图片,并构建绘图对象 */ @@ -175,30 +226,25 @@ public class QRCodeUtil { int matrixWidth = matrixImage.getWidth(); int matrixHeight = matrixImage.getHeight(); - /** - * 读取Logo图片 - */ - BufferedImage logo = ImageIO.read(logoFile); - //开始绘制图片 - g2.drawImage(logo,(int)(matrixWidth * PERCENT*2),(int)(matrixHeight * PERCENT*2), (int)(matrixWidth * PERCENT), (int)(matrixHeight * PERCENT), null);//绘制 - BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND); + g2.drawImage(logo, (int) (matrixWidth * PERCENT * 2), (int) (matrixHeight * PERCENT * 2), (int) (matrixWidth * PERCENT), (int) (matrixHeight * PERCENT), null);//绘制 + BasicStroke stroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); g2.setStroke(stroke);// 设置笔画对象 //指定弧度的圆角矩形 - RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth * PERCENT*2, matrixHeight * PERCENT*2, matrixWidth * PERCENT, matrixHeight * PERCENT,CORNER_RADIUS,CORNER_RADIUS); + RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth * PERCENT * 2, matrixHeight * PERCENT * 2, matrixWidth * PERCENT, matrixHeight * PERCENT, CORNER_RADIUS, CORNER_RADIUS); g2.setColor(Color.white); g2.draw(round);// 绘制圆弧矩形 //设置logo 有一道灰色边框 - BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND); + BasicStroke stroke2 = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); g2.setStroke(stroke2);// 设置笔画对象 - RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth * PERCENT*2+2, matrixHeight * PERCENT*2+2, matrixWidth * PERCENT-4, matrixHeight * PERCENT-4,CORNER_RADIUS,CORNER_RADIUS); - g2.setColor(new Color(128,128,128)); + RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth * PERCENT * 2 + 2, matrixHeight * PERCENT * 2 + 2, matrixWidth * PERCENT - 4, matrixHeight * PERCENT - 4, CORNER_RADIUS, CORNER_RADIUS); + g2.setColor(new Color(128, 128, 128)); g2.draw(round2);// 绘制圆弧矩形 g2.dispose(); - matrixImage.flush() ; - return matrixImage ; + matrixImage.flush(); + return matrixImage; } } diff --git a/src/main/java/org/yzr/utils/parser/APKParser.java b/src/main/java/org/yzr/utils/parser/APKParser.java index d613cfa..899b89a 100644 --- a/src/main/java/org/yzr/utils/parser/APKParser.java +++ b/src/main/java/org/yzr/utils/parser/APKParser.java @@ -5,7 +5,9 @@ import net.dongliu.apk.parser.bean.ApkMeta; import net.dongliu.apk.parser.bean.IconFace; import org.apache.commons.io.FileUtils; import org.yzr.model.Package; +import org.yzr.model.Storage; import org.yzr.utils.file.PathManager; +import org.yzr.utils.image.PNGConverter; import java.io.File; @@ -41,6 +43,11 @@ public class APKParser implements PackageParser { String iconPath = PathManager.getTempIconPath(aPackage); File iconFile = new File(iconPath); FileUtils.writeByteArrayToFile(iconFile, icon.getData()); + String sourceIconPath = PathManager.getTempFilePath("png"); + PNGConverter.convert(iconPath, sourceIconPath); + Storage iconStorage = new Storage(); + iconStorage.setUrl(sourceIconPath); + aPackage.setIconFile(iconStorage); } apkFile.close(); return aPackage; diff --git a/src/main/java/org/yzr/utils/parser/IPAParser.java b/src/main/java/org/yzr/utils/parser/IPAParser.java index 45e0e55..be0dbf6 100644 --- a/src/main/java/org/yzr/utils/parser/IPAParser.java +++ b/src/main/java/org/yzr/utils/parser/IPAParser.java @@ -4,6 +4,7 @@ import com.dd.plist.NSDate; import org.apache.commons.io.FileUtils; import org.yzr.model.Package; import org.yzr.model.Provision; +import org.yzr.model.Storage; import org.yzr.utils.file.PathManager; import org.yzr.utils.file.ZipUtil; import org.yzr.utils.image.PNGConverter; @@ -13,9 +14,7 @@ import org.yzr.utils.ipa.Plist; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; -import java.time.ZoneId; import java.util.ArrayList; - import java.util.List; import java.util.regex.Pattern; @@ -141,8 +140,11 @@ public class IPAParser implements PackageParser { // 获取应用图标 String iconName = infoPlist.getIconName(); String iconPath = appIcon(appPath, iconName); - String iconTempPath = PathManager.getTempIconPath(aPackage); - PNGConverter.convert(iconPath, iconTempPath); + String sourceIconPath = PathManager.getTempFilePath("png"); + PNGConverter.convert(iconPath, sourceIconPath); + Storage iconStorage = new Storage(); + iconStorage.setUrl(sourceIconPath); + aPackage.setIconFile(iconStorage); // 解析 Provision aPackage.setProvision(getProvision(appPath)); diff --git a/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java b/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java index ca1791f..3129dbd 100644 --- a/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java +++ b/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java @@ -3,12 +3,14 @@ package org.yzr.utils.webhook; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import okhttp3.*; +import org.springframework.core.io.Resource; import org.springframework.util.StringUtils; import org.yzr.model.App; import org.yzr.model.Package; import org.yzr.model.WebHook; -import org.yzr.utils.image.ImageUtils; +import org.yzr.storage.StorageUtil; import org.yzr.utils.file.PathManager; +import org.yzr.utils.image.ImageUtils; import org.yzr.utils.image.QRCodeUtil; import java.io.File; @@ -18,14 +20,16 @@ import java.util.Map; public class DingDingWebHook implements IWebHook { private static OkHttpClient client = new OkHttpClient(); + /** * 发送钉钉消息 + * * @param jsonString 消息内容 - * @param webhook 钉钉自定义机器人webhook + * @param webhook 钉钉自定义机器人webhook * @return */ private static boolean sendToDingding(String jsonString, String webhook) { - try{ + try { String type = "application/json; charset=utf-8"; RequestBody body = RequestBody.create(MediaType.parse(type), jsonString); Request.Builder builder = new Request.Builder().url(webhook); @@ -38,20 +42,20 @@ public class DingDingWebHook implements IWebHook { JSONObject result = JSONObject.parseObject(jsonString); System.out.println(result.getInteger("errcode")); return true; - }catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); return false; } } @Override - public void sendMessage(App app, PathManager pathManager) { + public void sendMessage(App app, String baseURL, StorageUtil storageUtil) { if (app.getWebHookList() == null || app.getWebHookList().size() < 1) { return; } Map markdown = new HashMap<>(); markdown.put("title", app.getName()); - String currentPackageURL = "/s/" + app.getShortCode() + "?id=" + app.getCurrentPackage().getId(); + String currentPackageURL = baseURL + "/s/" + app.getShortCode() + "?id=" + app.getCurrentPackage().getId(); String appURL = "/apps/" + app.getId(); String platform = "iOS"; if (app.getPlatform().equalsIgnoreCase("android")) { @@ -59,14 +63,17 @@ public class DingDingWebHook implements IWebHook { } String appInfo = String.format("[%s(%s)更新](%s)", app.getName(), platform, appURL); - - String iconPath = PathManager.getFullPath(app.getCurrentPackage()) + "icon.png"; + Resource resource = storageUtil.loadAsResource(app.getCurrentPackage().getIconFile().getKey()); // 将图片转为 base64, 内网 ip 钉钉无法访问,直接给图片数据 - String codePath = PathManager.getFullPath(app.getCurrentPackage()) + "code.jpg"; + String codePath = PathManager.getTempFilePath("jpg"); File codeFile = new File(codePath); // 图片不存在,生成图片 if (!codeFile.exists()) { - QRCodeUtil.encode(currentPackageURL).withSize(150, 150).withIcon(new File(iconPath)).writeTo(new File(codePath)); + try { + QRCodeUtil.encode(currentPackageURL).withSize(150, 150).withIcon(resource.getInputStream()).writeTo(codeFile); + } catch (Exception e) { + e.printStackTrace(); + } } String icon = "data:image/jpg;base64," + ImageUtils.convertImageToBase64(codePath); String pathInfo = String.format("![%s](%s)", app.getName(), icon); @@ -89,6 +96,7 @@ public class DingDingWebHook implements IWebHook { /** * 获取扩展消息 + * * @return */ private String getPackageMessage(Package aPackage) { diff --git a/src/main/java/org/yzr/utils/webhook/IWebHook.java b/src/main/java/org/yzr/utils/webhook/IWebHook.java index 665b8e3..e768954 100644 --- a/src/main/java/org/yzr/utils/webhook/IWebHook.java +++ b/src/main/java/org/yzr/utils/webhook/IWebHook.java @@ -1,8 +1,8 @@ package org.yzr.utils.webhook; import org.yzr.model.App; -import org.yzr.utils.file.PathManager; +import org.yzr.storage.StorageUtil; public interface IWebHook { - void sendMessage(App app, PathManager pathManager); + void sendMessage(App app, String baseURL, StorageUtil storageUtil); } diff --git a/src/main/java/org/yzr/utils/webhook/WebHookClient.java b/src/main/java/org/yzr/utils/webhook/WebHookClient.java index c318a57..7f6f3ff 100644 --- a/src/main/java/org/yzr/utils/webhook/WebHookClient.java +++ b/src/main/java/org/yzr/utils/webhook/WebHookClient.java @@ -2,8 +2,10 @@ package org.yzr.utils.webhook; import org.yzr.model.App; import org.yzr.model.WebHook; +import org.yzr.storage.StorageUtil; import org.yzr.utils.file.PathManager; +import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; @@ -18,9 +20,9 @@ public class WebHookClient { /** * 向 webHook 发送消息 * @param app - * @param pathManager + * @param baseURL */ - public static void sendMessage(App app, PathManager pathManager) { + public static void sendMessage(App app, String baseURL, StorageUtil storageUtil) { if (app.getWebHookList() == null || app.getWebHookList().size() < 1) { return; } @@ -30,7 +32,7 @@ public class WebHookClient { String webHookType = webHook.getType(); IWebHook iWebHook = getWebHook(webHookType); if (iWebHook != null) { - iWebHook.sendMessage(app, pathManager); + iWebHook.sendMessage(app, baseURL, storageUtil); } } } diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index eae818c..2afd54e 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -156,13 +156,13 @@ // 上传完成 xhr.onreadystatechange = function () { if (xhr.readyState === 4) { - var result = JSON.parse(xhr.response); + let result = JSON.parse(xhr.response); console.log(result); - var success = result.code == 0; + let success = result.code == 0; $.toast({text: result.msg, icon: success ? 'success' : 'error'}); if (success) { - // window.location.href = window.location.href; - // window.location.reload; + window.location.href = window.location.href; + window.location.reload; } }