提交 3ccb4c8a authored 作者: yangli's avatar yangli

Initial commit

上级
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.10</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.priusis</groupId>
<artifactId>haikang-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>haikang-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.2</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.11</version>
</dependency>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>3.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.priusis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class HaikangClientApplication {
public static void main(String[] args) {
SpringApplication.run(HaikangClientApplication.class, args);
}
}
package com.priusis;
import java.io.IOException;
/**
* @author yangli
* @since 2021/09/10
*/
public class Main {
public static void main(String[] args) throws IOException {
Runtime.getRuntime().exec("cmd /c C:\\Users\\lenovo\\Downloads\\3dbc34fcefbe4dd2a6a98c34e92dbe3f.msi");
}
}
package com.priusis.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}
package com.priusis.config;
import com.priusis.lib.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
/**
* @author yangli
* @since 2021/09/09
*/
@Slf4j
@RestControllerAdvice
public class ExceptionHandlerAdvice {
@ExceptionHandler(Exception.class)
public R<Void> exception(Exception e, HttpServletRequest req) {
log.error("uri: {}", req.getRequestURI(), e);
return R.error();
}
}
package com.priusis.controller;
import com.priusis.lib.R;
import com.priusis.util.SysConfigUtil;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.File;
import java.io.IOException;
import java.util.Map;
/**
* @author yangli
* @since 2021/09/10
*/
@Validated
@RestController
@RequestMapping(value = "config")
public class ConfigController {
@GetMapping(value = "get_download_path")
public R<String> getDownloadPath() throws IOException {
String path = SysConfigUtil.getProperty("download.path",
System.getProperty("user.home") + File.separator + "Downloads");
return R.success(path);
}
@PostMapping(value = "save_download_path")
public R<Void> saveDownloadPath(@RequestBody Map<String, String> params) throws IOException {
String path = params.get("path");
SysConfigUtil.saveProperty("download.path", path);
return R.success();
}
}
package com.priusis.controller;
import cn.hutool.core.io.unit.DataSizeUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.system.oshi.OshiUtil;
import com.priusis.lib.R;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import oshi.hardware.NetworkIF;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Map;
/**
* @author yangli
* @since 2021/09/06
*/
@RestController
@RequestMapping(value = "device_info")
public class DeviceInfoController {
@GetMapping(value = "get")
public R<Map<String, Object>> get() throws UnknownHostException, SocketException {
InetAddress inetAddress = InetAddress.getLocalHost();
NetworkIF networkIF = new NetworkIF();
networkIF.setNetworkInterface(NetworkInterface.getByInetAddress(inetAddress));
Map<String, Object> info = MapUtil.<String, Object>builder()
.put("operatingSystem", OshiUtil.getOs().toString())
.put("mac", networkIF.getMacaddr())
.put("baseboard", OshiUtil.getSystem().getBaseboard().getManufacturer() + " " + OshiUtil.getSystem().getBaseboard().getVersion())
.put("ip", inetAddress.getHostAddress())
.put("cpuModel", OshiUtil.getCpuInfo(0).getCpuModel())
.put("cpuTemp", OshiUtil.getSensors().getCpuTemperature())
.put("memoryCap", DataSizeUtil.format(OshiUtil.getMemory().getTotal()))
.put("diskModel", OshiUtil.getHardware().getDiskStores()[0].getModel())
.put("diskCap", DataSizeUtil.format(OshiUtil.getHardware().getDiskStores()[0].getSize()))
.build();
return R.success(info);
}
public static void main(String[] args) throws SocketException, UnknownHostException {
System.out.println("操作系统");
System.out.println(OshiUtil.getOs().toString());
System.out.println("MAC地址");
NetworkIF networkIF = new NetworkIF();
networkIF.setNetworkInterface(NetworkInterface.getByInetAddress(InetAddress.getLocalHost()));
System.out.println(networkIF.getMacaddr());
System.out.println("主板");
System.out.println(OshiUtil.getSystem().getBaseboard().getManufacturer() + " " + OshiUtil.getSystem().getBaseboard().getVersion());
System.out.println("IP");
System.out.println(InetAddress.getLocalHost().getHostAddress());
System.out.println("CPU型号");
System.out.println(OshiUtil.getCpuInfo(0).getCpuModel());
System.out.println("CPU温度");
System.out.println(OshiUtil.getSensors().getCpuTemperature());
System.out.println("内存容量");
System.out.println(DataSizeUtil.format(OshiUtil.getMemory().getTotal()));
System.out.println("硬盘型号");
System.out.println(OshiUtil.getHardware().getDiskStores()[0].getModel());
System.out.println("硬盘容量");
System.out.println(DataSizeUtil.format(OshiUtil.getHardware().getDiskStores()[0].getSize()));
}
}
package com.priusis.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.StreamProgress;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.priusis.lib.R;
import com.priusis.util.SysConfigUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author yangli
* @since 2021/09/07
*/
@Slf4j
@Validated
@RestController
@RequestMapping(value = "program")
public class ProgramController {
@Value(value = "${apq.iot-gateway}")
private String gateway;
@Value(value = "${apq.url.install}")
private String installUrl;
@Value(value = "${apq.url.upgrade}")
private String upgradeUrl;
private static List<Map<String, String>> programList;
@GetMapping(value = "{type}/list")
public R<Page<Map<String, String>>> list(@PathVariable @Pattern(regexp = "install|upgrade") String type,
@RequestParam(required = false, defaultValue = "1") Integer current,
@RequestParam(required = false, defaultValue = "10") Integer size)
throws IOException {
String url = gateway + StrUtil.format(type.equals("install") ? installUrl : upgradeUrl, current, size);
JSONObject rsp = JSONUtil.parseObj(HttpUtil.get(url));
if (ObjectUtil.notEqual(rsp.getInt("code"), 0)) return R.error(rsp.getStr("msg"));
Page<Map<String, String>> page = new Page<>();
page.setCurrent(current).setSize(size).setTotal(rsp.getLong("total"));
JSONArray rows = rsp.getJSONArray("rows");
if (CollUtil.isEmpty(rows)) return R.success(page.setRecords(Collections.emptyList()));
if (programList == null) loadProgramListJob();
List<Map<String, String>> programs = programList;
List<Map<String, String>> list = rows.stream().map(JSONObject.class::cast)
.map(o -> MapUtil.<String, String>builder()
.put("name", StrUtil.subBefore(o.getStr("fileName"), '.', true))
.put("size", o.getStr("fileSize"))
.put("version", o.getStr("version"))
.put("localVersion", null)
.put("url", o.getStr("url"))
.build())
.peek(m -> programs.stream()
.collect(Collectors.toMap(p -> StrUtil.similar(p.get("name").toLowerCase(), m.get("name").toLowerCase()),
p -> p.get("version"), (l, r) -> r))
.entrySet()
.stream()
.max(Map.Entry.comparingByKey())
.filter(e -> e.getKey() >= 0.5)
.ifPresent(e -> m.put("localVersion", e.getValue())))
.collect(Collectors.toList());
return R.success(page.setRecords(list));
}
@GetMapping(value = "download_and_install")
public void downloadAndInstall(@RequestParam @NotBlank String url, HttpServletResponse response) throws IOException {
File dir = new File(SysConfigUtil.getProperty("download.path",
System.getProperty("user.home") + File.separator + "Downloads"));
if (!dir.exists()) dir.mkdirs();
HttpResponse rsp = HttpUtil.createGet(url).execute(true);
double length = rsp.contentLength();
DecimalFormat decimalFormat = new DecimalFormat("0.#####");
File file = rsp.writeBodyForFile(dir, new StreamProgress() {
@SneakyThrows
@Override
public void start() {
response.getWriter().write("0\n");
}
@SneakyThrows
@Override
public void progress(long progressSize) {
response.getWriter().write(decimalFormat.format(progressSize / length) + "\n");
}
@SneakyThrows
@Override
public void finish() {
response.getWriter().close();
}
});
try {
Runtime.getRuntime().exec("cmd /c " + file.getPath());
} catch (Exception e) {
log.error("执行安装文件 {} 失败", file.getPath(), e);
}
}
@Scheduled(fixedDelay = 3000)
protected void loadProgramListJob() throws IOException {
List<Map<String, String>> programs = new ArrayList<>();
Process process = Runtime.getRuntime()
.exec("cmd /c reg query HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"))) {
String key;
while ((key = reader.readLine()) != null) {
Map<String, String> info = queryProgramInfo(key);
if (info.containsKey("name")) programs.add(info);
}
process.destroy();
}
programList = programs;
}
private Map<String, String> queryProgramInfo(String key) throws IOException {
Map<String, String> info = new HashMap<>();
Process process = Runtime.getRuntime().exec("cmd /c reg query " + key);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"))) {
reader.readLine();
reader.readLine();
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.startsWith("DisplayName")) {
info.put("name", line.replace("DisplayName", "").replace("REG_SZ", "").trim());
} else if (line.startsWith("DisplayVersion")) {
info.put("version", line.replace("DisplayVersion", "").replace("REG_SZ", "").trim());
}
}
process.destroy();
}
return info;
}
}
package com.priusis.lib;
import lombok.Getter;
@Getter
public class R<T> {
private final int code;
private final String msg;
private final T data;
private R(int code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public static <T> R<T> success(T data) {
return new R<>(0, "SUCCESS", data);
}
public static <T> R<T> success() {
return success(null);
}
public static <T> R<T> error(int code, String msg, T data) {
return new R<>(code, msg, data);
}
public static <T> R<T> error(int code, String msg) {
return error(code, msg, null);
}
public static <T> R<T> error(String msg) {
return error(500, msg);
}
public static <T> R<T> error() {
return error("系统异常");
}
}
package com.priusis.util;
import java.io.*;
import java.util.Properties;
/**
* @author yangli
* @since 2021/09/11
*/
public final class SysConfigUtil {
private SysConfigUtil() {
}
public static String getProperty(String key) throws IOException {
return getProperty(key, null);
}
public static String getProperty(String key, String defaultVal) throws IOException {
return loadProperties(configFile()).getProperty(key, defaultVal);
}
public static void saveProperty(String key, String val) throws IOException {
File file = configFile();
Properties properties = loadProperties(file);
properties.setProperty(key, val);
try (OutputStream out = new FileOutputStream(file)) {
properties.store(out, null);
}
}
private static Properties loadProperties(File file) throws IOException {
try (InputStream in = new FileInputStream(file)) {
Properties properties = new Properties();
properties.load(in);
return properties;
}
}
private static File configFile() throws IOException {
File dir = new File(System.getProperty("user.home") + File.separator + ".haikang");
if (!dir.exists()) dir.mkdirs();
File file = new File(dir, File.separator + "config.properties");
if (!file.exists()) file.createNewFile();
return file;
}
}
apq:
iot-gateway: 192.168.124.19:7002
url:
install: /ops/install/getList?pageNum={}&pageSize={}
upgrade: /ops/upgrade/getList?pageNum={}&pageSize={}
server:
port: 8765
spring:
application:
name: haikang-client
profiles:
active: dev
package com.priusis;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class HaikangClientApplicationTests {
@Test
void contextLoads() {
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论