diff --git a/build.gradle b/build.gradle
index c9c4843..b02fa79 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ plugins {
apply plugin: 'io.spring.dependency-management'
group = 'org.yzr'
-version = '1.0.0'
+version = '1.0.1'
sourceCompatibility = '1.8'
configurations {
@@ -28,11 +28,9 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.16'
- compileOnly 'org.projectlombok:lombok'
- annotationProcessor 'org.projectlombok:lombok'
compile group: 'com.googlecode.plist', name: 'dd-plist', version: '1.21'
compile group: 'net.dongliu', name: 'apk-parser', version: '2.6.9'
- compile group: 'net.glxn.qrgen', name: 'javase', version: '2.0'
+ compile group: 'com.google.zxing', name: 'javase', version: '3.4.0'
compile group: 'commons-io', name: 'commons-io', version: '2.6'
compile group: 'com.jcraft', name: 'jzlib', version: '1.1.3'
compile group: 'org.freemarker', name: 'freemarker', version: '2.3.28'
diff --git a/images/ding_ding.jpg b/images/ding_ding.jpg
index 5a5c0d1..54ed7dc 100644
Binary files a/images/ding_ding.jpg and b/images/ding_ding.jpg differ
diff --git a/src/main/java/org/yzr/controller/AppController.java b/src/main/java/org/yzr/controller/AppController.java
index 107c7eb..248e86b 100644
--- a/src/main/java/org/yzr/controller/AppController.java
+++ b/src/main/java/org/yzr/controller/AppController.java
@@ -11,7 +11,6 @@ import org.yzr.vo.AppViewModel;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
-import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -45,6 +44,20 @@ public class AppController {
return "list";
}
+ @RequestMapping("/packageList/{appID}")
+ @ResponseBody
+ public Map getAppPackageList(@PathVariable("appID") String appID) {
+ AppViewModel appViewModel = this.appService.getById(appID);
+ Map map = new HashMap<>();
+ try {
+ map.put("packages", appViewModel.getPackageList());
+ map.put("success", true);
+ } catch (Exception e) {
+ map.put("success", false);
+ }
+ return map;
+ }
+
@RequestMapping("/app/delete/{id}")
@ResponseBody
public Map deleteById(@PathVariable("id") String id) {
diff --git a/src/main/java/org/yzr/controller/PackageController.java b/src/main/java/org/yzr/controller/PackageController.java
index 91cf265..c26aeb5 100644
--- a/src/main/java/org/yzr/controller/PackageController.java
+++ b/src/main/java/org/yzr/controller/PackageController.java
@@ -1,10 +1,11 @@
package org.yzr.controller;
-import net.glxn.qrgen.javase.QRCode;
+import com.alibaba.fastjson.JSON;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Controller;
+import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.yzr.model.App;
@@ -12,6 +13,7 @@ import org.yzr.model.Package;
import org.yzr.service.AppService;
import org.yzr.service.PackageService;
import org.yzr.utils.PathManager;
+import org.yzr.utils.QRCodeUtil;
import org.yzr.utils.ipa.PlistGenerator;
import org.yzr.utils.webhook.WebHookClient;
import org.yzr.vo.AppViewModel;
@@ -88,6 +90,18 @@ public class PackageController {
try {
String filePath = transfer(file);
Package aPackage = this.packageService.buildPackage(filePath);
+ 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);
+ }
+ if (!extra.isEmpty()) {
+ aPackage.setExtra(JSON.toJSONString(extra));
+ }
App app = this.appService.getByPackage(aPackage);
app.getPackageList().add(aPackage);
app.setCurrentPackage(aPackage);
@@ -151,7 +165,7 @@ public class PackageController {
public void getManifest(@PathVariable("id") String id, HttpServletResponse response) {
try {
PackageViewModel viewModel = this.packageService.findById(id);
- if (viewModel != null && viewModel.isIOS()) {
+ if (viewModel != null && viewModel.isiOS()) {
response.setContentType("application/force-download");
response.setHeader("Content-Disposition", "attachment;fileName=manifest.plist");
Writer writer = new OutputStreamWriter(response.getOutputStream());
@@ -173,7 +187,7 @@ public class PackageController {
PackageViewModel viewModel = this.packageService.findById(id);
if (viewModel != null) {
response.setContentType("image/png");
- QRCode.from(viewModel.getPreviewURL()).withSize(250, 250).writeTo(response.getOutputStream());
+ QRCodeUtil.encode(viewModel.getPreviewURL()).withSize(250, 250).writeTo(response.getOutputStream());
}
} catch (Exception e) {
e.printStackTrace();
diff --git a/src/main/java/org/yzr/model/App.java b/src/main/java/org/yzr/model/App.java
index bb06cdf..2a62a24 100644
--- a/src/main/java/org/yzr/model/App.java
+++ b/src/main/java/org/yzr/model/App.java
@@ -1,8 +1,6 @@
package org.yzr.model;
-import lombok.Getter;
-import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
@@ -10,8 +8,6 @@ import java.util.List;
@Entity
@Table(name = "tb_app", uniqueConstraints = {@UniqueConstraint(columnNames={"platform", "bundleID"})})
-@Setter
-@Getter
public class App {
// 主键
@Id
@@ -43,4 +39,83 @@ public class App {
@JoinColumn(name = "currentID",referencedColumnName = "id")
private Package currentPackage;
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getBundleID() {
+ return bundleID;
+ }
+
+ public void setBundleID(String bundleID) {
+ this.bundleID = bundleID;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getShortCode() {
+ return shortCode;
+ }
+
+ public void setShortCode(String shortCode) {
+ this.shortCode = shortCode;
+ }
+
+ public String getPlatform() {
+ return platform;
+ }
+
+ public void setPlatform(String platform) {
+ this.platform = platform;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public long getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(long createTime) {
+ this.createTime = createTime;
+ }
+
+ public List getPackageList() {
+ return packageList;
+ }
+
+ public void setPackageList(List packageList) {
+ this.packageList = packageList;
+ }
+
+ public List getWebHookList() {
+ return webHookList;
+ }
+
+ public void setWebHookList(List webHookList) {
+ this.webHookList = webHookList;
+ }
+
+ public Package getCurrentPackage() {
+ return currentPackage;
+ }
+
+ public void setCurrentPackage(Package currentPackage) {
+ this.currentPackage = currentPackage;
+ }
}
diff --git a/src/main/java/org/yzr/model/Package.java b/src/main/java/org/yzr/model/Package.java
index d9a245f..45591c0 100644
--- a/src/main/java/org/yzr/model/Package.java
+++ b/src/main/java/org/yzr/model/Package.java
@@ -1,16 +1,12 @@
package org.yzr.model;
-import lombok.Getter;
-import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
@Entity
@Table(name="tb_package")
-@Setter
-@Getter
public class Package {
// 主键
@Id
@@ -34,6 +30,8 @@ public class Package {
private String minVersion;
// 平台(Android 或 iOS)
private String platform;
+ // 扩展消息 (json格式)
+ private String extra;
// 文件名
private String fileName;
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@@ -44,4 +42,107 @@ public class Package {
@JoinColumn(name = "provisionId",referencedColumnName = "id")
private Provision provision;
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getBundleID() {
+ return bundleID;
+ }
+
+ public void setBundleID(String bundleID) {
+ this.bundleID = bundleID;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getBuildVersion() {
+ return buildVersion;
+ }
+
+ public void setBuildVersion(String buildVersion) {
+ this.buildVersion = buildVersion;
+ }
+
+ public long getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(long createTime) {
+ this.createTime = createTime;
+ }
+
+ public long getSize() {
+ return size;
+ }
+
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+ public String getMinVersion() {
+ return minVersion;
+ }
+
+ public void setMinVersion(String minVersion) {
+ this.minVersion = minVersion;
+ }
+
+ public String getPlatform() {
+ return platform;
+ }
+
+ public void setPlatform(String platform) {
+ this.platform = platform;
+ }
+
+ public String getExtra() {
+ return extra;
+ }
+
+ public void setExtra(String extra) {
+ this.extra = extra;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public App getApp() {
+ return app;
+ }
+
+ public void setApp(App app) {
+ this.app = app;
+ }
+
+ public Provision getProvision() {
+ return provision;
+ }
+
+ public void setProvision(Provision provision) {
+ this.provision = provision;
+ }
}
diff --git a/src/main/java/org/yzr/model/Provision.java b/src/main/java/org/yzr/model/Provision.java
index fc9cfe8..95f3c11 100644
--- a/src/main/java/org/yzr/model/Provision.java
+++ b/src/main/java/org/yzr/model/Provision.java
@@ -1,7 +1,5 @@
package org.yzr.model;
-import lombok.Getter;
-import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
@@ -10,8 +8,6 @@ import java.util.Date;
@Entity
@Table(name="tb_provision")
-@Setter
-@Getter
public class Provision {
// 主键
@Id
@@ -29,4 +25,84 @@ public class Provision {
private int deviceCount;
private String type;
private boolean isEnterprise;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getTeamName() {
+ return teamName;
+ }
+
+ public void setTeamName(String teamName) {
+ this.teamName = teamName;
+ }
+
+ public String getTeamID() {
+ return teamID;
+ }
+
+ public void setTeamID(String teamID) {
+ this.teamID = teamID;
+ }
+
+ public Date getCreateDate() {
+ return createDate;
+ }
+
+ public void setCreateDate(Date createDate) {
+ this.createDate = createDate;
+ }
+
+ public Date getExpirationDate() {
+ return expirationDate;
+ }
+
+ public void setExpirationDate(Date expirationDate) {
+ this.expirationDate = expirationDate;
+ }
+
+ public String getUUID() {
+ return UUID;
+ }
+
+ public void setUUID(String UUID) {
+ this.UUID = UUID;
+ }
+
+ public String[] getDevices() {
+ return devices;
+ }
+
+ public void setDevices(String[] devices) {
+ this.devices = devices;
+ }
+
+ public int getDeviceCount() {
+ return deviceCount;
+ }
+
+ public void setDeviceCount(int deviceCount) {
+ this.deviceCount = deviceCount;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public boolean isEnterprise() {
+ return isEnterprise;
+ }
+
+ public void setEnterprise(boolean enterprise) {
+ isEnterprise = enterprise;
+ }
}
diff --git a/src/main/java/org/yzr/model/WebHook.java b/src/main/java/org/yzr/model/WebHook.java
index 11f7e1e..04b09b5 100644
--- a/src/main/java/org/yzr/model/WebHook.java
+++ b/src/main/java/org/yzr/model/WebHook.java
@@ -1,16 +1,12 @@
package org.yzr.model;
-import lombok.Getter;
-import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
@Entity
@Table(name = "tb_web_hook")
-@Setter
-@Getter
public class WebHook {
// 钉钉
public static final String WEB_HOOK_TYPE_DING_DING="DingDing";
@@ -31,4 +27,44 @@ public class WebHook {
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinColumn(name="appId")
private App app;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public App getApp() {
+ return app;
+ }
+
+ public void setApp(App app) {
+ this.app = app;
+ }
}
diff --git a/src/main/java/org/yzr/service/PackageService.java b/src/main/java/org/yzr/service/PackageService.java
index ef50da6..af2a1c3 100644
--- a/src/main/java/org/yzr/service/PackageService.java
+++ b/src/main/java/org/yzr/service/PackageService.java
@@ -1,22 +1,17 @@
package org.yzr.service;
-import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Service;
-import org.yzr.dao.AppDao;
import org.yzr.dao.PackageDao;
-import org.yzr.model.App;
import org.yzr.model.Package;
import org.yzr.utils.ImageUtils;
import org.yzr.utils.PathManager;
-import org.yzr.utils.ipa.PlistGenerator;
import org.yzr.utils.parser.ParserClient;
import org.yzr.vo.PackageViewModel;
import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.io.File;
@@ -39,12 +34,9 @@ public class PackageService {
String tempIconPath = PathManager.getTempIconPath(aPackage);
String iconPath = packagePath + File.separator + "icon.png";
String sourcePath = packagePath + File.separator + fileName;
- String jpgIconPath = packagePath + File.separator + "icon.jpg";
// 拷贝图标
ImageUtils.resize(tempIconPath, iconPath, 192, 192);
- // 生成钉钉发送所需要图片
- ImageUtils.convertPNGToJPG(iconPath, jpgIconPath, 64, 64);
// 源文件
FileUtils.copyFile(new File(filePath), new File(sourcePath));
diff --git a/src/main/java/org/yzr/utils/QRCodeUtil.java b/src/main/java/org/yzr/utils/QRCodeUtil.java
new file mode 100644
index 0000000..ac7f767
--- /dev/null
+++ b/src/main/java/org/yzr/utils/QRCodeUtil.java
@@ -0,0 +1,204 @@
+package org.yzr.utils;
+
+import com.google.zxing.*;
+import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
+import com.google.zxing.client.j2se.MatrixToImageConfig;
+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 javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+public class QRCodeUtil {
+
+ private String text;
+
+ private Integer width = 200;
+
+ private Integer height = 200;
+
+ private static final float PERCENT = 0.2F;
+
+ private static final int CORNER_RADIUS = 5;
+
+ private File icon;
+
+ private String format = "png";
+
+ public static QRCodeUtil encode(String text) {
+ QRCodeUtil util = new QRCodeUtil();
+ util.text = text;
+ return util;
+ }
+
+ public QRCodeUtil withSize(Integer width, Integer height) {
+ this.width = width;
+ this.height = height;
+ return this;
+ }
+
+ public QRCodeUtil withIcon(File icon) {
+ this.icon = icon;
+ 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);
+ ImageIO.write(bufferedImage, format, outputStream);
+ } else {
+ MatrixToImageWriter.writeToStream(bitMatrix, format, outputStream);
+ }
+ return true;
+ } catch (WriterException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public boolean writeTo(File file) {
+ try {
+ BitMatrix bitMatrix = getBitMatrix();
+ if (this.icon != null) {
+ MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF);
+ BufferedImage bufferedImage = drawIconInMatrix(MatrixToImageWriter.toBufferedImage(bitMatrix,matrixToImageConfig), this.icon);
+ ImageIO.write(bufferedImage, format, file);
+ } else {
+ MatrixToImageWriter.writeToPath(bitMatrix, format, file.toPath());
+ }
+ return true;
+ } catch (WriterException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ private BitMatrix getBitMatrix() throws WriterException {
+ Map hints = new HashMap<>();
+ //内容编码格式
+ hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
+ // 指定纠错等级
+ hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
+ //设置二维码边的空度,非负数
+ hints.put(EncodeHintType.MARGIN, 1);
+ return new MultiFormatWriter().encode(this.text, BarcodeFormat.QR_CODE, width, height, hints);
+ }
+
+
+ /**
+ * 识别指定文件的二维码
+ * @param file
+ * @return
+ */
+ public static String parseCode(File file) {
+ BufferedImage bufferedImage = null;
+ try {
+ bufferedImage = ImageIO.read(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return parseCode(bufferedImage);
+ }
+
+ /**
+ * 识别指定图片的二维码
+ * @param bufferedImage
+ * @return
+ */
+ public static String parseCode(BufferedImage bufferedImage) {
+ String content = null;
+ try {
+ //读取指定的二维码文件
+ MultiFormatReader formatReader = new MultiFormatReader();
+ BinaryBitmap binaryBitmap= new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage)));
+ //定义二维码参数
+ 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());
+ content = result.getText();
+ if (bufferedImage != null) {
+ bufferedImage.flush();
+ }
+ } catch (NotFoundException e) {
+ e.printStackTrace();
+ }
+ return content;
+ }
+
+ /**
+ * 识别输入流的二维码
+ * @param inputStream
+ * @return
+ */
+ public static String parseCode(InputStream inputStream) {
+ BufferedImage bufferedImage = null;
+ try {
+ bufferedImage = ImageIO.read(inputStream);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return parseCode(bufferedImage);
+ }
+
+ /**
+ * 二维码添加logo
+ * @param matrixImage 源二维码图片
+ * @param logoFile logo图片
+ * @return 返回带有logo的二维码图片
+ */
+ private BufferedImage drawIconInMatrix(BufferedImage matrixImage, File logoFile) throws IOException{
+ /**
+ * 读取二维码图片,并构建绘图对象
+ */
+ Graphics2D g2 = matrixImage.createGraphics();
+ 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.setStroke(stroke);// 设置笔画对象
+ //指定弧度的圆角矩形
+ 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);
+ 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));
+ g2.draw(round2);// 绘制圆弧矩形
+
+ g2.dispose();
+ matrixImage.flush() ;
+ return matrixImage ;
+ }
+}
+
diff --git a/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java b/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java
index 6ece4e1..3c17c0f 100644
--- a/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java
+++ b/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java
@@ -1,12 +1,17 @@
package org.yzr.utils.webhook;
+import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
+import org.springframework.util.StringUtils;
import org.yzr.model.App;
+import org.yzr.model.Package;
import org.yzr.model.WebHook;
import org.yzr.utils.ImageUtils;
import org.yzr.utils.PathManager;
+import org.yzr.utils.QRCodeUtil;
+import java.io.File;
import java.util.HashMap;
import java.util.Map;
@@ -46,19 +51,30 @@ public class DingDingWebHook implements IWebHook {
}
Map markdown = new HashMap<>();
markdown.put("title", app.getName());
- String url = pathManager.getBaseURL(false) + "s/" + app.getShortCode();
+ String url = pathManager.getBaseURL(false) + "s/" + app.getShortCode() + "?id=" + app.getCurrentPackage().getId();
String platform = "iOS";
if (app.getPlatform().equalsIgnoreCase("android")) {
platform = "Android";
}
String appInfo = String.format("[%s(%s)更新](%s)", app.getName(), platform, url);
+
+ String iconPath = PathManager.getFullPath(app.getCurrentPackage()) + "icon.png";
// 将图片转为 base64, 内网 ip 钉钉无法访问,直接给图片数据
- String iconPath = PathManager.getFullPath(app.getCurrentPackage()) + "icon.jpg";
- String icon = "data:image/jpg;base64," + ImageUtils.convertImageToBase64(iconPath);
+ String codePath = PathManager.getFullPath(app.getCurrentPackage()) + "code.jpg";
+ File codeFile = new File(codePath);
+ // 图片不存在,生成图片
+ if (!codeFile.exists()) {
+ QRCodeUtil.encode(url).withSize(150, 150).withIcon(new File(iconPath)).writeTo(new File(codePath));
+ }
+ String icon = "data:image/jpg;base64," + ImageUtils.convertImageToBase64(codePath);
String pathInfo = String.format("", app.getName(), icon);
String otherInfo = String.format("链接:[%s](%s) \n\n 版本:%s (Build: %s)", url, url, app.getCurrentPackage().getVersion(), app.getCurrentPackage().getBuildVersion());
+ String message = this.getPackageMessage(app.getCurrentPackage());
String text = appInfo + " \n\n " + pathInfo + " \n\n " + otherInfo;
+ if (message.length() > 0) {
+ text += "\n\n" + message;
+ }
markdown.put("text", text);
JSONObject jsonObject = new JSONObject();
jsonObject.put("msgtype", "markdown");
@@ -69,4 +85,23 @@ public class DingDingWebHook implements IWebHook {
sendToDingding(json, webHook.getUrl());
}
}
+
+ /**
+ * 获取扩展消息
+ * @return
+ */
+ private String getPackageMessage(Package aPackage) {
+ String message = "";
+ if (StringUtils.hasLength(aPackage.getExtra())) {
+ Map extra = (Map) JSON.parse(aPackage.getExtra());
+ if (extra.containsKey("jobName")) {
+ message += "任务名:" + extra.get("jobName");
+ }
+
+ if (extra.containsKey("buildNumber")) {
+ message += " 编号:#" + extra.get("buildNumber");
+ }
+ }
+ return message;
+ }
}
diff --git a/src/main/java/org/yzr/vo/AppViewModel.java b/src/main/java/org/yzr/vo/AppViewModel.java
index 1668b95..9e1f08d 100644
--- a/src/main/java/org/yzr/vo/AppViewModel.java
+++ b/src/main/java/org/yzr/vo/AppViewModel.java
@@ -1,18 +1,13 @@
package org.yzr.vo;
-import lombok.Data;
-import lombok.Getter;
-import lombok.Setter;
import org.yzr.model.App;
import org.yzr.model.Package;
import org.yzr.utils.PathManager;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.List;
-@Getter
public class AppViewModel {
private String id;
@@ -106,4 +101,52 @@ public class AppViewModel {
});
return packageViewModels;
}
+
+ public String getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPlatform() {
+ return platform;
+ }
+
+ public String getBundleID() {
+ return bundleID;
+ }
+
+ public String getIcon() {
+ return icon;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public String getBuildVersion() {
+ return buildVersion;
+ }
+
+ public String getMinVersion() {
+ return minVersion;
+ }
+
+ public String getShortCode() {
+ return shortCode;
+ }
+
+ public String getInstallPath() {
+ return installPath;
+ }
+
+ public List getPackageList() {
+ return packageList;
+ }
+
+ public PackageViewModel getCurrentPackage() {
+ return currentPackage;
+ }
}
diff --git a/src/main/java/org/yzr/vo/PackageViewModel.java b/src/main/java/org/yzr/vo/PackageViewModel.java
index 22960e5..b806a9a 100644
--- a/src/main/java/org/yzr/vo/PackageViewModel.java
+++ b/src/main/java/org/yzr/vo/PackageViewModel.java
@@ -1,18 +1,18 @@
package org.yzr.vo;
-import lombok.Getter;
+import com.alibaba.fastjson.JSON;
import org.apache.commons.io.FileUtils;
+import org.springframework.util.StringUtils;
import org.yzr.model.Package;
import org.yzr.utils.PathManager;
import java.net.URLEncoder;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
+import java.util.Map;
-@Getter
public class PackageViewModel {
private String downloadURL;
private String safeDownloadURL;
@@ -31,6 +31,7 @@ public class PackageViewModel {
private String type;
private List devices;
private int deviceCount;
+ private String message;
public PackageViewModel(Package aPackage, PathManager pathManager) {
this.downloadURL = pathManager.getBaseURL(false) + "p/" + aPackage.getId();
@@ -57,7 +58,7 @@ public class PackageViewModel {
this.installURL = pathManager.getPackageResourceURL(aPackage, false) + aPackage.getFileName();
}
this.previewURL = pathManager.getBaseURL(false) + "s/" + aPackage.getApp().getShortCode() + "?id=" + aPackage.getId();
- if (this.isIOS()) {
+ if (this.isiOS()) {
if (aPackage.getProvision() == null) {
this.type = "内测版";
} else {
@@ -78,6 +79,89 @@ public class PackageViewModel {
} else {
this.type = "内测版";
}
+ String message = "";
+ if (StringUtils.hasLength(aPackage.getExtra())) {
+ Map extra = (Map) JSON.parse(aPackage.getExtra());
+ if (extra.containsKey("jobName")) {
+ message += " 任务名:" + extra.get("jobName");
+ }
+
+ if (extra.containsKey("buildNumber")) {
+ message += " 编号:#" + extra.get("buildNumber");
+ }
+ }
+ this.message = message;
}
+ public String getDownloadURL() {
+ return downloadURL;
+ }
+
+ public String getSafeDownloadURL() {
+ return safeDownloadURL;
+ }
+
+ public String getIconURL() {
+ return iconURL;
+ }
+
+ public String getInstallURL() {
+ return installURL;
+ }
+
+ public String getPreviewURL() {
+ return previewURL;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public String getBundleID() {
+ return bundleID;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public long getCreateTime() {
+ return createTime;
+ }
+
+ public String getBuildVersion() {
+ return buildVersion;
+ }
+
+ public String getDisplaySize() {
+ return displaySize;
+ }
+
+ public String getDisplayTime() {
+ return displayTime;
+ }
+
+ public boolean isiOS() {
+ return iOS;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public List getDevices() {
+ return devices;
+ }
+
+ public int getDeviceCount() {
+ return deviceCount;
+ }
+
+ public String getMessage() {
+ return message;
+ }
}
diff --git a/src/main/java/org/yzr/vo/WebHookViewModel.java b/src/main/java/org/yzr/vo/WebHookViewModel.java
index 5715283..4eeabee 100644
--- a/src/main/java/org/yzr/vo/WebHookViewModel.java
+++ b/src/main/java/org/yzr/vo/WebHookViewModel.java
@@ -1,8 +1,5 @@
package org.yzr.vo;
-import lombok.Data;
-
-@Data
public class WebHookViewModel {
private String id;
@@ -14,4 +11,44 @@ public class WebHookViewModel {
private String type;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getAppId() {
+ return appId;
+ }
+
+ public void setAppId(String appId) {
+ this.appId = appId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
}
diff --git a/src/main/resources/static/js/list.js b/src/main/resources/static/js/list.js
index a5e30e1..8f6eaf4 100644
--- a/src/main/resources/static/js/list.js
+++ b/src/main/resources/static/js/list.js
@@ -2,16 +2,16 @@
* 获取 webHook 列表
*/
function getWebHooks() {
- var appId =$("#appId").val();
+ var appId = $("#appId").val();
var url = "/webHook/find/" + appId;
- $.post(url, function(result){
+ $.post(url, function (result) {
$(".configrations").children(".config-name").remove();
- var content="";
+ var content = "";
for (var i = 0; i < result.length; i++) {
content += '#'+ result[i].name +' ';
+ content += 'data="' + result[i].id + '" data-url="' + result[i].url + '" ';
+ content += 'data-name="' + result[i].name;
+ content += '">#' + result[i].name + '';
}
$(".configrations").append(content);
});
@@ -44,6 +44,84 @@ function editWebHook(e) {
}
}
+/**
+ * 获取包列表
+ */
+function getPackageList() {
+ var appId = $("#appId").val();
+ var url = "/packageList/" + appId;
+ $.post(url, function (result) {
+ if (result.success) {
+ var packages = result.packages;
+ var packageList = '';
+ packageList += '';
+ packageList += ' ';
+ packageList += '版本更新 ';
+ packageList += ' ';
+ packageList += ' ';
+ packageList += '';
+ packageList += '';
+ packageList += '
';
+ packageList += ' ';
+ for (var i = 0; i < packages.length; i++) {
+ var package = packages[i];
+ var version = package.version;
+ var buildVersion = package.buildVersion;
+ var displayTime = package.displayTime;
+ var type = package.type;
+ var downloadURL = package.downloadURL;
+ var displaySize = package.displaySize;
+ var previewURL = package.previewURL;
+ var id = package.id;
+ var message = package.message;
+ packageList += '';
+ packageList += '';
+ packageList += '
';
+ packageList += '
';
+ packageList += '
' + version + ' (Build ' + buildVersion + ')' + message + ' ';
+ packageList += '
';
+ packageList += ' ';
+ packageList += '' + displayTime + ' ';
+ packageList += ' ';
+ packageList += '
';
+ packageList += '
';
+ packageList += ' ';
+ packageList += '' + displayTime + ' · ';
+ packageList += '' + type + ' ';
+ packageList += ' · ';
+ packageList += ' ';
+ packageList += '
';
+ packageList += '
';
+ packageList += '';
+ packageList += ' ';
+ packageList += ' ' + displaySize + ' ';
+ packageList += ' ';
+ packageList += '';
+ packageList += ' ';
+ packageList += ' 预览 ';
+ packageList += ' ';
+ if (i > 0) {
+ packageList += '';
+ packageList += ' ';
+ packageList += ' 删除 ';
+ packageList += ' ';
+ }
+ packageList += '
';
+ packageList += '
';
+ packageList += '
';
+ packageList += ' ';
+ }
+ packageList += '';
+ packageList += '显示更多版本 ';
+ $("#app-activity-panel").empty();
+ $("#app-activity-panel").append(packageList);
+
+ bindActions();
+ }
+ });
+
+}
+
/**
* 构造数据
* @returns {{appId: (*|jQuery|string|undefined), name: (*|jQuery|string|undefined), id: (*|jQuery|string|undefined), url: (*|jQuery|string|undefined)}}
@@ -53,11 +131,11 @@ function buildData() {
var url = $("#ding-ding-web-hook-url").val();
var appId = $("#appId").val();
var id = $("#webHookId").val();
- var data ={
- name:name,
- url:url,
- appId:appId,
- id:id
+ var data = {
+ name: name,
+ url: url,
+ appId: appId,
+ id: id
};
return data;
}
@@ -110,7 +188,7 @@ function remove() {
function postWithURL(url) {
var data = buildData();
resetForm();
- $.post(url, data, function(result){
+ $.post(url, data, function (result) {
getWebHooks();
});
}
@@ -130,9 +208,10 @@ function removeAllPanelClass() {
$("#app-integration-panel").removeClass("ng-hide");
}
-$(function () {
- getWebHooks();
-
+/**
+ * 绑定事件
+ */
+function bindActions() {
$(".download-action").click(function () {
window.open($(this).val())
});
@@ -142,12 +221,23 @@ $(function () {
});
$(".app-delete").click(function () {
- var url = "/p/delete/" + $(this).attr("data");
- $.post(url, function(result){
- window.location.href = window.location.href
- window.location.reload
+ var id = $(this).attr("data");
+ var url = "/p/delete/" + id;
+ var li = "package_index_" + id;
+ console.log(li);
+ var self = $("." + li);
+ $.post(url, function (result) {
+ if (result.success) {
+ self.remove();
+ }
});
- })
+ });
+}
+
+$(function () {
+ getPackageList();
+ getWebHooks();
+
$("#js-app-short-copy-trigger").click(function () {
new ClipboardJS('#js-app-short-copy-trigger', {
text: function (trigger) {
@@ -180,12 +270,12 @@ $(function () {
$("#delete-app").click(function () {
var url = "/app/delete/" + $(this).attr("data");
- $.post(url, function(result){
+ $.post(url, function (result) {
window.location.href = "/apps"
});
});
- $("#ding-ding-web-hook-name, #ding-ding-web-hook-url").bind("input propertychange",function(event){
+ $("#ding-ding-web-hook-name, #ding-ding-web-hook-url").bind("input propertychange", function (event) {
var name = $("#ding-ding-web-hook-name").val();
var url = $("#ding-ding-web-hook-url").val();
if (name.length > 0 && url.length > 0) {
diff --git a/src/main/resources/templates/install.html b/src/main/resources/templates/install.html
index d646297..f2e19d7 100644
--- a/src/main/resources/templates/install.html
+++ b/src/main/resources/templates/install.html
@@ -59,6 +59,7 @@
[[${app.version}]] (Build [[${app.buildVersion}]]) -
[[${app.currentPackage.displaySize}]]
更新于: [[${app.currentPackage.displayTime}]]
+ [[${app.currentPackage.message}]]
diff --git a/src/main/resources/templates/list.html b/src/main/resources/templates/list.html
index 09988cb..0e2064a 100644
--- a/src/main/resources/templates/list.html
+++ b/src/main/resources/templates/list.html
@@ -1,62 +1,67 @@
+
[[${package.name}]] - 应用动态
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
- [[${package.installPath}]]
- iOS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
[[${package.installPath}]]
+
iOS
Android
BundleID [[${package.bundleID}]]
iOS [[${package.minVersion}]] 或者高版本
@@ -83,53 +88,6 @@
-
-
- 版本更新
-
-
-
-
-
-
-
-
-
-
-
[[${app.version}]] (Build [[${app.buildVersion}]])
-
-
-
- [[${app.displayTime}]]
-
-
-
-
-
- [[${app.displayTime}]] ·
- [[${app.type}]]
- ·
-
-
-
-
-
- [[${app.displaySize}]]
-
-
-
- 预览
-
-
-
- 删除
-
-
-
-
-
-
- 显示更多版本