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("![%s](%s)", 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 += ''; + 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 += ''; + if (i > 0) { + 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.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}]] - 应用动态 - + + - - - -
    -
    -