Merge branch 'master' of gitee.com:yizhaorong/intranet_app_manager

This commit is contained in:
yizhaorong
2019-08-10 13:39:35 +08:00
35 changed files with 272 additions and 8565 deletions
+4
View File
@@ -0,0 +1,4 @@
*.js linguist-language=java
*.css linguist-language=java
*.html linguist-language=java
*.java linguist-language=java
+13 -3
View File
@@ -13,6 +13,12 @@
![首页](images/install.jpg)
![首页](images/mobile_install.jpg)
##### 证书信任设置
![首页](images/install_crt.gif)
#### 安装教程
项目使用 JAVA 开发,需要 JDK 1.8 运行环境,数据库使用的是 Mysql,需要安装 Mysql。JDK 安装直接找网上教程。
@@ -33,7 +39,7 @@ mysql -u root -p
```shell
# 创建库
create database app_manager;
create database app_manager DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
```
##### HTTPS 证书
@@ -56,7 +62,7 @@ create database app_manager;
#### 部署
本项目使用的是 80 和 443 端口,确保端口未被占用。
本项目使用的是 80 和 443 端口,确保端口未被占用。可以配置文件中更改为别的端口。
> 启动服务
@@ -68,7 +74,11 @@ java -jar intranet_app_manager-1.0.0.jar
> 上传与安装
可以将 ipa 或 apk 拖入上传块中进行上传,上传完成后会在列表中展示。iOS 安装需要使用 https 协议,由于内网部署是用的自建证书,需要将 ca 添加到设备的信用列表中才可正常进行安装。
可以将 ipa 或 apk 拖入上传块中进行上传,上传完成后会在列表中展示。
**注意**
本项目默认采用 http 方式访问,这样可以避免没必要的证书信任。iOS 安装需要使用 https 协议,由于内网部署是用的自建证书,需要将 ca 添加到设备的信用列表中才可正常进行安装。**设置抓包代理会影响自建证书**,导致无法下载。
#### Jenkins 集成
+1 -1
View File
@@ -29,7 +29,7 @@ localityName_default=HangZhou
organizationalUnitName=Organizational Unit Name (eg, section)
organizationalUnitName_default=Domain Control Validated
commonName=Internet Widgits Ltd
commonName_default=192.168.0.*
commonName_default=DigiCert APP Manager Root CA
commonName_max=64
[ v3_req ]
BIN
View File
Binary file not shown.
Regular → Executable
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Regular → Executable
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Regular → Executable
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 KiB

Regular → Executable
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Regular → Executable
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 27 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Regular → Executable
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 32 KiB

BIN
View File
Binary file not shown.
@@ -45,9 +45,35 @@ public class PackageController {
AppViewModel viewModel = this.appService.findByCode(code, id);
request.setAttribute("app", viewModel);
request.setAttribute("ca_path", this.pathManager.getCAPath());
request.setAttribute("basePath", this.pathManager.getBaseURL(false));
return "install";
}
/**
* 设备列表
* @param id
* @param request
* @return
*/
@GetMapping("/devices/{id}")
public String devices(@PathVariable("id") String id, HttpServletRequest request) {
PackageViewModel viewModel= this.packageService.findById(id);
request.setAttribute("app", viewModel);
return "devices";
}
/**
* 安装教程
* @param platform
* @param request
* @return
*/
@GetMapping("/guide/{platform}")
public String guide(@PathVariable("platform") String platform, HttpServletRequest request) {
request.setAttribute("platform", platform);
return "guide";
}
/**
* 上传包
* @param file
@@ -182,7 +208,7 @@ public class PackageController {
// 生成文件名
String newFileName = UUID.randomUUID().toString() + "." + ext;
// 转存到 tmp
String destPath = FileUtils.getTempDirectory() + newFileName;
String destPath = FileUtils.getTempDirectoryPath() + File.separator + newFileName;
srcFile.transferTo(new File(destPath));
return destPath;
} catch (Exception e) {
+4
View File
@@ -39,5 +39,9 @@ public class Package {
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinColumn(name="appId")
private App app;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
// Provision 文件
@JoinColumn(name = "provisionId",referencedColumnName = "id")
private Provision provision;
}
@@ -0,0 +1,32 @@
package org.yzr.model;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name="tb_provision")
@Setter
@Getter
public class Provision {
// 主键
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(length = 32)
private String id;
private String teamName;
private String teamID;
private Date createDate;
private Date expirationDate;
private String UUID;
@Column(length = 80000)
private String[] devices;
private int deviceCount;
private String type;
private boolean isEnterprise;
}
+10 -2
View File
@@ -46,7 +46,7 @@ public class PathManager {
}
int httpPort = Integer.parseInt(environment.getProperty("server.http.port"));
int httpsPort = Integer.parseInt(environment.getProperty("server.port"));
int port = isHttps ? httpPort : httpsPort;
int port = isHttps ? httpsPort : httpPort;
String protocol = isHttps ? "https" : "http";
String portString = ":" + port;
if (port == 80 || port == 443) {
@@ -54,6 +54,14 @@ public class PathManager {
}
String baseURL = protocol + "://" + domain + portString + "/";
//解决重复读配置文件
if (isHttps) {
httpsBaseURL = baseURL;
} else {
httpBaseURL = baseURL;
}
return baseURL;
} catch (Exception e) {
e.printStackTrace();
@@ -88,7 +96,7 @@ public class PathManager {
public static String getTempIconPath(Package aPackage) {
if (aPackage == null) return null;
StringBuilder path = new StringBuilder();
path.append(FileUtils.getTempDirectoryPath()).append(aPackage.getPlatform());
path.append(FileUtils.getTempDirectoryPath()).append(File.separator).append(aPackage.getPlatform());
path.append(File.separator).append(aPackage.getBundleID());
// 如果目录不存在,创建目录
File dir = new File(path.toString());
+1 -1
View File
@@ -14,7 +14,7 @@ public class ZipUtils {
public static String unzip(String path) {
try {
long start = System.currentTimeMillis();
String destDirPath = System.getProperty("java.io.tmpdir") + start;
String destDirPath = FileUtils.getTempDirectoryPath() + File.separator + start;
ZipFile zipFile = new ZipFile(path);
Enumeration<?> entries = zipFile.entries();
while (entries.hasMoreElements()) {
+12 -7
View File
@@ -1,9 +1,6 @@
package org.yzr.utils.ipa;
import com.dd.plist.NSArray;
import com.dd.plist.NSDictionary;
import com.dd.plist.NSObject;
import com.dd.plist.PropertyListParser;
import com.dd.plist.*;
import java.io.File;
import java.util.ArrayList;
@@ -81,18 +78,26 @@ public class Plist {
}
public List<String> arrayValueForPath(String path) {
List<String> devices = new ArrayList<>();
Object object = valueForKeyPath(path);
if (object != null) {
NSArray deviceArray = (NSArray)object;
List<String> devices = new ArrayList<>();
if (deviceArray != null && deviceArray.count() > 0) {
for (int i = 0; i < deviceArray.count(); i++) {
devices.add(deviceArray.objectAtIndex(i).toString());
}
}
return devices;
}
return null;
return devices;
}
public boolean boolValueForPath(String keyPath) {
Object object = valueForKeyPath(keyPath);
if (object instanceof NSNumber) {
NSNumber number = (NSNumber)object;
return number.boolValue();
}
return false;
}
}
@@ -1,56 +0,0 @@
package org.yzr.utils.ipa;
import com.dd.plist.NSDate;
import lombok.Getter;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Date;
import java.util.List;
@Getter
public class Provision {
private String teamName;
private String teamID;
private Date createDate;
private Date expirationDate;
private String UUID;
private List<String> devices;
private int deviceCount;
private String type;
public Provision(String appPath) {
String profile = appPath + File.separator + "embedded.mobileprovision";
try {
boolean started = false;
boolean ended = false;
BufferedReader reader = new BufferedReader(new FileReader(profile));
StringBuffer plist = new StringBuffer();
String str = null;
while ((str = reader.readLine()) != null) {
if (str.contains("</plist>")) {
ended = true;
plist.append("</plist>").append("\n");
} else if (started && !ended) {
plist.append(str).append("\n");
} else if (str.contains("<?xml")) {
started = true;
plist.append(str.substring(str.indexOf("<?xml"))).append("\n");
}
}
reader.close();
Plist provisionFile = Plist.parseWithString(plist.toString());
this.devices = provisionFile.arrayValueForPath("ProvisionedDevices");
this.deviceCount = this.devices.size();
this.teamName = provisionFile.stringValueForPath("TeamName");
this.teamID = provisionFile.arrayValueForPath("TeamIdentifier").get(0);
this.createDate = ((NSDate)provisionFile.valueForKeyPath("CreationDate")).getDate();
this.expirationDate = ((NSDate)provisionFile.valueForKeyPath("ExpirationDate")).getDate();
this.UUID = provisionFile.stringValueForPath("UUID");
this.type = this.deviceCount > 0 ? "Ad-hoc" : "Release";
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,17 +1,19 @@
package org.yzr.utils.parser;
import com.dd.plist.NSDate;
import org.apache.commons.io.FileUtils;
import org.yzr.model.Package;
import org.yzr.utils.PNGConverter;
import org.yzr.utils.PathManager;
import org.yzr.utils.ZipUtils;
import org.yzr.utils.ipa.Plist;
import org.yzr.utils.ipa.Provision;
import org.yzr.model.Provision;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;
public class IPAParser implements PackageParser {
@@ -49,7 +51,7 @@ public class IPAParser implements PackageParser {
PNGConverter.convert(iconPath, iconTempPath);
// 解析 Provision
Provision provision = new Provision(appPath);
aPackage.setProvision(getProvision(appPath));
// 清除目录
FileUtils.deleteDirectory(new File(targetPath));
@@ -100,4 +102,44 @@ public class IPAParser implements PackageParser {
}
return null;
}
private static Provision getProvision(String appPath) {
Provision provision = new Provision();
String profile = appPath + File.separator + "embedded.mobileprovision";
try {
boolean started = false;
boolean ended = false;
BufferedReader reader = new BufferedReader(new FileReader(profile));
StringBuffer plist = new StringBuffer();
String str = null;
while ((str = reader.readLine()) != null) {
if (str.contains("</plist>")) {
ended = true;
plist.append("</plist>").append("\n");
} else if (started && !ended) {
plist.append(str).append("\n");
} else if (str.contains("<?xml")) {
started = true;
plist.append(str.substring(str.indexOf("<?xml"))).append("\n");
}
}
reader.close();
Plist provisionFile = Plist.parseWithString(plist.toString());
provision.setEnterprise(provisionFile.boolValueForPath("ProvisionsAllDevices"));
List<String> provisionedDevices = provisionFile.arrayValueForPath("ProvisionedDevices");
String[] devices = new String[provisionedDevices.size()];
devices = provisionedDevices.toArray(devices);
provision.setDevices(devices);
provision.setDeviceCount(devices.length);
provision.setTeamName(provisionFile.stringValueForPath("TeamName"));
provision.setTeamID(provisionFile.arrayValueForPath("TeamIdentifier").get(0));
provision.setCreateDate(((NSDate)provisionFile.valueForKeyPath("CreationDate")).getDate());
provision.setExpirationDate(((NSDate)provisionFile.valueForKeyPath("ExpirationDate")).getDate());
provision.setUUID(provisionFile.stringValueForPath("UUID"));
provision.setType(provision.getDeviceCount() > 0 ? "AdHoc" : "Release");
} catch (Exception e) {
e.printStackTrace();
}
return provision;
}
}
@@ -6,7 +6,10 @@ 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;
@Getter
@@ -25,6 +28,9 @@ public class PackageViewModel {
private String displaySize;
private String displayTime;
private boolean iOS;
private String type;
private List<String> devices;
private int deviceCount;
public PackageViewModel(Package aPackage, PathManager pathManager) {
this.downloadURL = pathManager.getBaseURL(false) + "p/" + aPackage.getId();
@@ -51,6 +57,27 @@ 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 (aPackage.getProvision() == null) {
this.type = "内测版";
} else {
if (aPackage.getProvision().isEnterprise()) {
this.type = "企业版";
} else {
if ("AdHoc".equalsIgnoreCase(aPackage.getProvision().getType())) {
this.type = "内测版";
} else {
this.type = "商店版";
}
this.deviceCount = aPackage.getProvision().getDeviceCount();
if (aPackage.getProvision().getDeviceCount() > 0) {
this.devices = Arrays.asList(aPackage.getProvision().getDevices());
}
}
}
} else {
this.type = "内测版";
}
}
}
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -1,7 +1,7 @@
########################################################
### Mysql
########################################################
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/app_manager
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/app_manager?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
@@ -41,4 +41,4 @@ server.ssl.key-alias=1
server.port=443
server.http.port=80
config.debug=debug
server.domain=192.168.0.108
server.domain=127.0.0.1
File diff suppressed because one or more lines are too long
-459
View File
@@ -1,459 +0,0 @@
@font-face {
font-family: partner;
src: url(./fonts/ipartner.eot?rkodm6);
src: url(./fonts/ipartner.eot?rkodm6#iefix) format("embedded-opentype"), url(./fonts/ipartner.ttf?rkodm6) format("truetype"), url(./fonts/ipartner.woff?rkodm6) format("woff"), url(./fonts/ipartner.svg?rkodm6#ipartner) format("svg");
font-weight: 400;
font-style: normal
}
[class*=" ipartner-"], [class^=ipartner-] {
font-family: partner!important;
speak: none;
font-style: normal;
font-weight: 400;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale
}
.ipartner-swift:before {
content: "\e900"
}
.ipartner-qingcloud:before {
content: "\e902"
}
.ipartner-devlink:before {
content: "\e920"
}
.ipartner-logo-pingxx:before {
content: "\e921"
}
.ipartner-logo-qiniu:before {
content: "\e922"
}
.ipartner-logo-leancloud:before {
content: "\e923"
}
.ipartner-logo-flowci:before {
content: "\e924"
}
.ipartner-deveco:before {
content: "\e925"
}
.ipartner-wilddog:before {
content: "\e926"
}
.ipartner-xitu:before {
content: "\e927"
}
.ipartner-36kr:before {
content: "\e928"
}
@font-face {
font-family: icomoon;
src: url(./fonts/icomoon.eot?wcusdg);
src: url(./fonts/icomoon.eot?wcusdg#iefix) format("embedded-opentype"), url(./fonts/icomoon.ttf?wcusdg) format("truetype"), url(./fonts/icomoon.woff?wcusdg) format("woff"), url(./fonts/icomoon.svg?wcusdg#icomoon) format("svg");
font-weight: 400;
font-style: normal
}
[class*=" icon-"], [class^=icon-] {
font-family: icomoon!important;
speak: none;
font-style: normal;
font-weight: 400;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale
}
.icon-cake:before {
content: "\e900"
}
.icon-weibo:before {
content: "\e600"
}
.icon-wechat:before {
content: "\e601"
}
.icon-firim:before {
content: "\e602"
}
.icon-bug:before {
content: "\e603"
}
.icon-ion:before {
content: "\e604"
}
.icon-angle-right:before {
content: "\e606"
}
.icon-cloud-download:before {
content: "\e607"
}
.icon-question:before {
content: "\e608"
}
.icon-optimize-upload:before {
content: "\e609"
}
.icon-console:before {
content: "\e60a"
}
.icon-microscope:before {
content: "\e60b"
}
.icon-user-access:before {
content: "\e60c"
}
.icon-logo-jiecao:before {
content: "\e60d"
}
.icon-m:before {
content: "\e60e"
}
.icon-f:before {
content: "\e60f"
}
.icon-plugin:before {
content: "\e610"
}
.icon-launch:before {
content: "\e611"
}
.icon-brace-left:before {
content: "\e613"
}
.icon-logo:before {
content: "\e620"
}
.icon-thumbsup:before {
content: "\e615"
}
.icon-webhooks:before {
content: "\e616"
}
.icon-brace-right:before {
content: "\e617"
}
.icon-comma-eye:before {
content: "\e618"
}
.icon-mouth:before {
content: "\e619"
}
.icon-brace-hor:before {
content: "\e61a"
}
.icon-brace-right-b:before {
content: "\e61b"
}
.icon-brace-left-b:before {
content: "\e61c"
}
.icon-brace-box:before {
content: "\e61d"
}
.icon-menu:before {
content: "\e61e"
}
.icon-app:before {
content: "\e61f"
}
.icon-box:before {
content: "\e620"
}
.icon-combo:before {
content: "\e621"
}
.icon-device:before {
content: "\e622"
}
.icon-face:before {
content: "\e623"
}
.icon-file:before {
content: "\e624"
}
.icon-msg:before {
content: "\e625"
}
.icon-pen:before {
content: "\e626"
}
.icon-ipa:before {
content: "\e627"
}
.icon-lock2:before {
content: "\e628"
}
.icon-qrcode:before {
content: "\e629"
}
.icon-rollback:before {
content: "\e62a"
}
.icon-eye:before {
content: "\e62b"
}
.icon-plus:before {
content: "\e62c"
}
.icon-chart:before {
content: "\e62d"
}
.icon-idea:before {
content: "\e62e"
}
.icon-owner:before {
content: "\e62f"
}
.icon-search:before {
content: "\e630"
}
.icon-studio:before {
content: "\e631"
}
.icon-upload-cloud2:before {
content: "\e632"
}
.icon-android:before {
content: "\e633"
}
.icon-trash:before {
content: "\e634"
}
.icon-attachment:before {
content: "\e635"
}
.icon-apple:before {
content: "\e636"
}
.icon-calendar:before {
content: "\e637"
}
.icon-calendar2:before {
content: "\e638"
}
.icon-eye-close:before {
content: "\e639"
}
.icon-reply:before {
content: "\e63a"
}
.icon-email:before {
content: "\e63b"
}
.icon-error2:before {
content: "\e63c"
}
.icon-cross:before {
content: "\e63d"
}
.icon-user-plus:before {
content: "\e63e"
}
.icon-ios:before {
content: "\e63f"
}
.icon-filter:before {
content: "\e640"
}
.icon-test-speed:before {
content: "\e641"
}
.icon-udid:before {
content: "\e642"
}
.icon-update:before {
content: "\e643"
}
.icon-comma:before {
content: "\e644"
}
.icon-i:before {
content: "\e645"
}
.icon-r:before {
content: "\e646"
}
.icon-f-dot:before {
content: "\e647"
}
.icon-layers:before {
content: "\e648"
}
.icon-news:before {
content: "\e649"
}
.icon-percent:before {
content: "\e64a"
}
.icon-bughd:before {
content: "\e64b"
}
.icon-incode:before {
content: "\e64c"
}
.icon-message:before {
content: "\e64d"
}
.icon-eclipse:before {
content: "\e64e"
}
.icon-turkey:before {
content: "\e901"
}
.icon-jenkins:before {
content: "\e902"
}
.icon-gradle:before {
content: "\e903"
}
.icon-statistics:before {
content: "\e904"
}
.icon-done:before {
content: "\e905"
}
.icon-qiniu:before {
content: "\e906"
}
.icon-logo-leancloud:before {
content: "\e907"
}
.icon-logo-jd:before {
content: "\e908"
}
.icon-logo-xiachufang:before {
content: "\e909"
}
.icon-logo-ebaoyang:before {
content: "\e90a"
}
.icon-logo-jumei:before {
content: "\e90b"
}
.icon-cart:before {
content: "\e90c"
}
.icon-users:before {
content: "\e90d"
}
.icon-spinner3:before {
content: "\e97c"
}
.icon-infinite:before {
content: "\ea2f"
}
.icon-spinner:before {
content: "\f110"
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

File diff suppressed because one or more lines are too long
+29
View File
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<meta name="viewport"
content="minimal-ui,width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<title>[[${app.name}]]-设备列表</title>
<link rel="icon" type="image/x-icon" th:href="@{/images/favicon.ico}" />
<link rel="stylesheet" th:href="@{/css/bootstrap.css}">
</head>
<body>
<div class="card container">
<div class="list-group text-center">
<a href="#" class="list-group-item active">
<h4 class="list-group-item-heading">
设备ID
</h4>
</a>
<a class="list-group-item" href="#" th:each="device,appStat : ${app.devices}">
[[${device}]]
</a>
</div>
</div>
</body>
</html>
+25
View File
@@ -0,0 +1,25 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Stict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<title class="ng-binding">[[${platform}]] - 安装教程</title>
<link rel="icon" type="image/x-icon" th:href="@{/images/favicon.ico}" />
<link rel="stylesheet" th:href="@{/css/icons.css}">
<link rel="stylesheet" th:href="@{/css/bootstrap.css}">
<link rel="stylesheet" th:href="@{/css/manage.css}">
<link rel="stylesheet" th:href="@{/css/index.css}">
<script type="text/javascript" th:src="@{/js/jquery-1.11.0.min.js}"></script>
</head>
<body>
<div class="guide">
<img th:src="@{/images/install_crt.gif}"/>
</div>
</body>
</html>
-2
View File
@@ -8,9 +8,7 @@
<title>应用列表</title>
<link rel="icon" type="image/x-icon" th:href="@{/images/favicon.ico}" />
<link rel="stylesheet" th:href="@{/css/icons.css}">
<link rel="stylesheet" th:href="@{/css/bootstrap.css}">
<link rel="stylesheet" th:href="@{/css/manage.css}">
<link rel="stylesheet" th:href="@{/css/index.css}">
<script type="text/javascript" th:src="@{/js/jquery-1.11.0.min.js}"></script>
+21 -3
View File
@@ -42,7 +42,7 @@
</span>
</div>
<p class="release-type wrapper">内测版</p>
<p class="release-type wrapper">[[${app.currentPackage.type}]]</p>
<h1 class="name wrapper">
<span class="icon-warp">
@@ -54,7 +54,7 @@
<p class="scan-tips">扫描二维码下载<br>或用手机浏览器输入这个网址:&nbsp;&nbsp;<span
class="text-black">[[${app.installPath}]]</span></p>
<div class="release-info">
<p>内测版 -
<p>[[${app.currentPackage.type}]] -
<span itemprop="softwareVersion">[[${app.version}]] (Build [[${app.buildVersion}]]) -
[[${app.currentPackage.displaySize}]]</span></p>
<p>更新于: <span itemprop="datePublished">[[${app.currentPackage.displayTime}]]</span></p>
@@ -64,11 +64,21 @@
<div class="action-animate-text" id="install">下载安装</div>
<div class="action-animate-active"></div>
</div>
<div class="action-animate">
<div class="action-animate" th:if="${#strings.containsIgnoreCase(app.platform,'ios')}">
<input id="crtURL" th:value="${ca_path}" style="display: none"/>
<div class="action-animate-text" id="installCRT">安装证书</div>
<div class="action-animate-active"></div>
</div>
<div class="action-animate" th:if="${app.currentPackage.deviceCount > 0}">
<input id="devices" th:value="${basePath} + 'devices/' + ${app.currentPackage.id}" style="display: none"/>
<div class="action-animate-text" id="showDevices">查看设备列表</div>
<div class="action-animate-active"></div>
</div>
<div class="action-animate" th:if="${#strings.containsIgnoreCase(app.platform,'ios')}">
<input id="trust_crt" th:value="${basePath} + 'guide/ios'" style="display: none"/>
<div class="action-animate-text" id="trustCTR">证书信任教程</div>
<div class="action-animate-active"></div>
</div>
</div>
</div>
</div>
@@ -86,6 +96,14 @@
window.open($("#crtURL").val())
})
$("#showDevices").click(function () {
window.open($("#devices").val())
})
$("#trustCTR").click(function () {
window.open($("#trust_crt").val())
})
var codeData = $("#qrcode").attr("data");
new QRCode("qrcode", {
text: codeData,
+10 -3
View File
@@ -8,11 +8,10 @@
<title class="ng-binding">[[${package.name}]] - 应用动态</title>
<link rel="icon" type="image/x-icon" th:href="@{/images/favicon.ico}" />
<link rel="stylesheet" th:href="@{/css/icons.css}">
<link rel="stylesheet" th:href="@{/css/bootstrap.css}">
<link rel="stylesheet" th:href="@{/css/manage.css}">
<link rel="stylesheet" th:href="@{/css/index.css}">
<script type="text/javascript" th:src="@{/js/jquery-1.11.0.min.js}"></script>
<script type="text/javascript" th:src="@{/js/clipboard.min.js}"></script>
</head>
<body class="ng-scope">
@@ -108,7 +107,7 @@
<small>
<i class="icon-calendar"></i>
<span class="ng-binding">[[${app.displayTime}]]</span></small> &nbsp;&nbsp;·&nbsp;&nbsp;
<small class="ng-scope">内测版</small>
<small class="ng-scope">[[${app.type}]]</small>
<i class="ng-hide">&nbsp;&nbsp;·&nbsp;&nbsp;</i>
<small class="ng-binding ng-hide"></small>
</div>
@@ -155,6 +154,14 @@
}
});
})
$("#js-app-short-copy-trigger").click(function(){
new ClipboardJS('#js-app-short-copy-trigger', {
text: function(trigger) {
return trigger.getAttribute('value');
}
});
});
</script>
</body>