提交 4de9d50a authored 作者: wangqiang's avatar wangqiang

采集程序、硬件检测程序、软件检测程序与远程桌面程序集成为一个安装包

上级 2294e1a6
......@@ -139,6 +139,13 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.priusis</groupId>
<artifactId>apq-pc-common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
......
package com.priusis.client.extensions.http;
import com.fasterxml.jackson.databind.JsonNode;
import com.priusis.client.data.kv.KvEntry;
import com.priusis.client.extensions.ExtensionUpdate;
import com.priusis.client.extensions.http.conf.HttpConfiguration;
......
......@@ -3,8 +3,6 @@ package com.priusis.client.service;
import com.google.common.collect.Lists;
import com.priusis.client.service.conf.PcConnectionConfiguration;
import com.priusis.client.service.conf.PcPersistenceConfiguration;
import com.priusis.client.service.core.MqttService;
import com.priusis.client.service.core.MqttServiceImpl;
import com.priusis.monitor.mqtt.MqttClient;
import com.priusis.monitor.mqtt.MqttConnectResult;
import com.priusis.monitor.mqtt.MqttHandler;
......
apq:
iot-gateway: 10.2.68.40:7033
job:
type: all
PC_HOST: 10.2.68.40
vnc-repeater: 10.2.68.41:5500
\ No newline at end of file
......@@ -16,9 +16,9 @@
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${pkg.logFolder}/${pkg.name}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
<maxFileSize>10MB</maxFileSize>
<maxHistory>3</maxHistory>
<totalSizeCap>100MB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
......
<?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 http://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>apq-pc-common</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring-boot.version>2.4.10</spring-boot.version>
<jna.version>3.0.9</jna.version>
<pkg.user>priusis-iot</pkg.user>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.11</version>
</dependency>
<dependency>
<groupId>com.sun.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.priusis.job;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.priusis.dto.RegisterParamDto;
import com.priusis.utils.WinExecuteUtils;
import com.priusis.vo.MqttRpcDataMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
@ConditionalOnExpression("'${apq.job.type:null}'=='all' || '${apq.job.type:null}'=='register'")
public class ApqRegisterJob {
// "params":
// {
// "type":1
// "programs": [
// {
// "name":"qq"
// }
// ]
// }
@Autowired
private RestTemplate restTemplate;
@Scheduled(fixedDelay = 30000L)
protected void registerProgramTask() {
log.info("软件检测上报=================");
/* try {
WinExecuteUtils.killProc("TIM.exe");
} catch (IOException e) {
log.error("杀进程异常", e);
}*/
// 获取软件检测监控配置 params == data
ResponseEntity<MqttRpcDataMessage> forEntity = null;
try {
forEntity = restTemplate.getForEntity("http://localhost:8765/rpc_cmd/register", MqttRpcDataMessage.class);
} catch (RestClientException e) {
log.error("软件检测上报异常", e.getMessage());
}
if (null != forEntity) {
MqttRpcDataMessage body = forEntity.getBody();
String params = body.getParams();
if (StrUtil.isNotBlank(params)) {
Long sendTime = body.getSendTime();
//long current = System.currentTimeMillis();
RegisterParamDto registerParamDto = JSONUtil.toBean(params, RegisterParamDto.class);
// 收到软件检测下发请求
log.info("收到软件检测下发请求, sendTime:{}, params:{}", sendTime, params);
int type = registerParamDto.getType();
if (type == 1) {
List<RegisterParamDto.RegisterDetailParamDto> programs = registerParamDto.getPrograms();
// 上报软件检测监控数据
Map mapRequest = new HashMap();
for (RegisterParamDto.RegisterDetailParamDto program : programs) {
String name = program.getName().trim();
log.info("软件检测软件: {}", name);
boolean isE = WinExecuteUtils.findProcess(name);
if (isE) {
// 杀进程
log.info("存在黑名单软件, 进行进程查杀: {}", name);
try {
WinExecuteUtils.killProc(name);
} catch (Exception e) {
log.error("杀进程异常", e);
}
// 上报黑名单异常
mapRequest.put(name, "1");
}
}
// 上报黑名单异常
if (mapRequest.size() > 0) {
Map eventMapRequest = new HashMap();
eventMapRequest.put("requestId", 1);
eventMapRequest.put("methodName", "BlackList");
eventMapRequest.put("params", mapRequest);
Map map = restTemplate.postForObject("http://localhost:8765/uplink_event/oc-client", eventMapRequest, Map.class);
log.info("存在软件检测接口扫码告警,上报告警事件: mapData:{}, ret:{}", mapRequest, map);
}
// 上报黑名单属性 todo
}
} else {
log.info("未获取到获取软件检测监控配置");
}
} else {
log.info("未获取到获取软件检测监控配置");
}
}
}
......@@ -2,13 +2,7 @@ package com.priusis.utils;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.system.ApplicationHome;
import java.io.File;
import java.io.UnsupportedEncodingException;
/******************************************************************************************************************************
......
package com.priusis.util;
package com.priusis.utils;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
......
package com.priusis.util;
package com.priusis.utils;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
......
package com.priusis;
import com.priusis.vo.MqttRpcDataMessage;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
public class RestTest {
@Autowired
private RestTemplate restTemplate;
@Test
public void test1() throws Exception {
// 获取硬件监控配置 params == data
ResponseEntity<MqttRpcDataMessage> forEntity = restTemplate.getForEntity("http://localhost:8765/rpc_cmd/controll", MqttRpcDataMessage.class);
System.out.println(forEntity.getBody().getMethod());
System.out.println(forEntity.getBody().getParams());
// 上报硬件监控数据
Map mapRequest = new HashMap();
Map map = restTemplate.postForObject("http://localhost:8765/uplink/oc-client", mapRequest, Map.class);
System.out.println(map);
}
}
......@@ -57,25 +57,10 @@
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.11</version>
</dependency>
<dependency>
<groupId>com.sun.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<groupId>com.priusis</groupId>
<artifactId>apq-pc-common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
......
......@@ -6,4 +6,8 @@ server:
# Server bind address
address: "0.0.0.0"
# port: ${random.int[10000,19999]}
port: 8762
\ No newline at end of file
port: 8762
apq:
job:
type: control
\ No newline at end of file
......@@ -16,9 +16,9 @@
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${pkg.logFolder}/${pkg.name}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
<maxFileSize>10MB</maxFileSize>
<maxHistory>3</maxHistory>
<totalSizeCap>100MB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
......
......@@ -44,6 +44,13 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.priusis</groupId>
<artifactId>apq-pc-common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
......@@ -55,17 +62,6 @@
<scope>test</scope>
</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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
......
......@@ -7,7 +7,7 @@ import cn.hutool.json.JSONUtil;
import cn.hutool.system.oshi.CpuInfo;
import cn.hutool.system.oshi.OshiUtil;
import com.priusis.lib.R;
import com.priusis.util.MacAddrUtil;
import com.priusis.utils.MacAddrUtil;
import com.priusis.vo.ApqInfoDataVo;
import com.priusis.vo.MqttRpcDataMessage;
import lombok.extern.slf4j.Slf4j;
......
package com.priusis.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class MqttRpcDataMessage implements Serializable {
private static final long serialVersionUID = -3133461476074777891L;
private int requestId;
private String method;
private String params;
@Override
public String toString() {
return "{requestId=" + requestId +
", method=" + method +
", params=" + params +
'}';
}
}
......@@ -7,3 +7,7 @@ server:
address: "0.0.0.0"
# port: ${random.int[10000,19999]}
port: 8764
apq:
job:
type: info
\ No newline at end of file
......@@ -16,9 +16,9 @@
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${pkg.logFolder}/${pkg.name}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
<maxFileSize>10MB</maxFileSize>
<maxHistory>3</maxHistory>
<totalSizeCap>100MB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
......
......@@ -3,7 +3,7 @@ package com.priusis;
import cn.hutool.core.io.unit.DataSizeUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.system.oshi.OshiUtil;
import com.priusis.util.MacAddrUtil;
import com.priusis.utils.MacAddrUtil;
import com.priusis.vo.MqttRpcDataMessage;
import org.junit.Test;
import org.junit.runner.RunWith;
......
......@@ -56,16 +56,10 @@
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.11</version>
<groupId>com.priusis</groupId>
<artifactId>apq-pc-common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
......
package com.priusis;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.priusis.dto.RegisterParamDto;
import com.priusis.util.WinExecuteUtils;
import com.priusis.vo.MqttRpcDataMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@EnableScheduling
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, SecurityAutoConfiguration.class})
public class ApqRegisterApplication {
......@@ -30,92 +14,5 @@ public class ApqRegisterApplication {
SpringApplication.run(ApqRegisterApplication.class, args);
}
// "params":
// {
// "type":1
// "programs": [
// {
// "name":"qq"
// }
// ]
// }
@Autowired
private RestTemplate restTemplate;
@Scheduled(fixedDelay = 30000L)
protected void registerProgramTask() {
log.info("软件检测上报=================");
/* try {
WinExecuteUtils.killProc("TIM.exe");
} catch (IOException e) {
log.error("杀进程异常", e);
}*/
// 获取软件检测监控配置 params == data
ResponseEntity<MqttRpcDataMessage> forEntity = null;
try {
forEntity = restTemplate.getForEntity("http://localhost:8765/rpc_cmd/register", MqttRpcDataMessage.class);
} catch (RestClientException e) {
log.error("软件检测上报异常", e.getMessage());
}
if (null != forEntity) {
MqttRpcDataMessage body = forEntity.getBody();
String params = body.getParams();
if (StrUtil.isNotBlank(params)) {
Long sendTime = body.getSendTime();
//long current = System.currentTimeMillis();
RegisterParamDto registerParamDto = JSONUtil.toBean(params, RegisterParamDto.class);
// 收到软件检测下发请求
log.info("收到软件检测下发请求, sendTime:{}, params:{}", sendTime, params);
int type = registerParamDto.getType();
if (type == 1) {
List<RegisterParamDto.RegisterDetailParamDto> programs = registerParamDto.getPrograms();
// 上报软件检测监控数据
Map mapRequest = new HashMap();
for (RegisterParamDto.RegisterDetailParamDto program : programs) {
String name = program.getName().trim();
log.info("软件检测软件: {}", name);
boolean isE = WinExecuteUtils.findProcess(name);
if (isE) {
// 杀进程
log.info("存在黑名单软件, 进行进程查杀: {}", name);
try {
WinExecuteUtils.killProc(name);
} catch (Exception e) {
log.error("杀进程异常", e);
}
// 上报黑名单异常
mapRequest.put(name, "1");
}
}
// 上报黑名单异常
if (mapRequest.size() > 0) {
Map eventMapRequest = new HashMap();
eventMapRequest.put("requestId", 1);
eventMapRequest.put("methodName", "BlackList");
eventMapRequest.put("params", mapRequest);
Map map = restTemplate.postForObject("http://localhost:8765/uplink_event/oc-client", eventMapRequest, Map.class);
log.info("存在软件检测接口扫码告警,上报告警事件: mapData:{}, ret:{}", mapRequest, map);
}
// 上报黑名单属性 todo
}
} else {
log.info("未获取到获取软件检测监控配置");
}
} else {
log.info("未获取到获取软件检测监控配置");
}
}
}
package com.priusis.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class MqttRpcDataMessage implements Serializable {
private static final long serialVersionUID = -3133461476074777891L;
private int requestId;
private String method;
private Long sendTime;
private String params;
@Override
public String toString() {
return "{requestId=" + requestId +
", sendTime=" + sendTime +
", method=" + method +
", params=" + params +
'}';
}
}
......@@ -6,4 +6,8 @@ server:
# Server bind address
address: "0.0.0.0"
# port: ${random.int[30000,39999]}
port: 8763
\ No newline at end of file
port: 8763
apq:
job:
type: register
\ No newline at end of file
......@@ -16,9 +16,9 @@
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${pkg.logFolder}/${pkg.name}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
<maxFileSize>10MB</maxFileSize>
<maxHistory>3</maxHistory>
<totalSizeCap>100MB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
......
......@@ -11,6 +11,7 @@
<name>apq-client</name>
<modules>
<module>apq-pc-common</module>
<module>apq-pc-client</module>
<module>apq-pc-control</module>
<module>apq-pc-info</module>
......
......@@ -17,8 +17,8 @@
-->
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Apache_Logo_Horizontal" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" viewBox="0 0 9835 1713.9" enable-background="new 0 0 9835 1713.9" xml:space="preserve">
<svg version="1.1" id="Apache_Logo_Horizontal" xmlns="http://www.w3.org/2000/svg"
x="0px" y="0px" viewBox="0 0 9835 1713.9" enable-background="new 0 0 9835 1713.9" xml:space="preserve">
<path fill="#6D6E71" d="M1069.6,296.4v92.2h-11.8v-92.2h-33.7V285h79.4v11.4H1069.6z"/>
<path fill="#6D6E71" d="M1234.8,388.5V343h-62.4v45.6h-11.8V285h11.8v46.8h62.4V285h11.8v103.6H1234.8z"/>
<path fill="#6D6E71" d="M1329.2,296.4v34h52.2v11.4h-52.2v35.5h60.4v11.3h-72.2V285h70.3v11.4H1329.2z"/>
......
......@@ -29,11 +29,11 @@
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg
xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;" i:viewOrigin="176.7139 486.707" i:rulerOrigin="-156 -296" i:pageBounds="156 496 456 296"
xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
width="260.162" height="184.413" viewBox="0 0 260.162 184.413" overflow="visible" enable-background="new 0 0 260.162 184.413"
xml:space="preserve">
<svg
xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" i:viewOrigin="176.7139 486.707" i:rulerOrigin="-156 -296" i:pageBounds="156 496 456 296"
xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;"
width="260.162" height="184.413" viewBox="0 0 260.162 184.413" overflow="visible" enable-background="new 0 0 260.162 184.413"
xml:space="preserve">
<metadata>
<variableSets xmlns="&ns_vars;">
<variableSet varSetName="binding1" locked="none">
......@@ -46,14 +46,14 @@
<sliceSourceBounds y="302.294" x="176.714" width="260.162" height="184.413" bottomLeftOrigin="true"></sliceSourceBounds>
</sfw>
<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?><x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='XMP toolkit 3.0-29, framework 1.6'>
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'>
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<rdf:Description rdf:about=''
xmlns:pdf='http://ns.adobe.com/pdf/1.3/'>
>
</rdf:Description>
<rdf:Description rdf:about=''
xmlns:tiff='http://ns.adobe.com/tiff/1.0/'>
<rdf:Description rdf:about=''
>
</rdf:Description>
<rdf:Description rdf:about=''
......
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论