mirror of
https://gitee.com/shuto-github/intranet_app_manager.git
synced 2026-05-27 00:00:14 +08:00
完善存储逻辑
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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<String, String> 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<String, String> 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<String, String> getExtraParams(HttpServletRequest request) {
|
||||
Map<String, String> 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()) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String, String> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,65 +77,66 @@ public class PackageService {
|
||||
@Transactional
|
||||
public Package save(String filePath, Map<String, String> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ public class UserService {
|
||||
String[] perms = new String[]{
|
||||
"/apps",
|
||||
"/apps/get",
|
||||
"/apps/delete",
|
||||
"/app/delete",
|
||||
"/packageList/get"
|
||||
};
|
||||
for (String string : perms) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传路径
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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<String, Object> 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("", app.getName(), icon);
|
||||
@@ -89,6 +96,7 @@ public class DingDingWebHook implements IWebHook {
|
||||
|
||||
/**
|
||||
* 获取扩展消息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String getPackageMessage(Package aPackage) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user