This commit is contained in:
huoyo 2020-12-10 18:54:29 +08:00
commit 2753146fdb
134 changed files with 2188 additions and 0 deletions

11
.idea/$PROJECT_FILE$ generated Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AnalysisProjectProfileManager">
<option name="PROJECT_PROFILE" />
<option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
<list size="0" />
</component>
<component name="SuppressionsComponent">
<option name="suppComments" value="[]" />
</component>
</project>

8
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

13
.idea/compiler.xml generated Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="ko-time" />
</profile>
</annotationProcessing>
</component>
</project>

20
.idea/jarRepositories.xml generated Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

17
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="SuppressionsComponent">
<option name="suppComments" value="[]" />
</component>
</project>

12
.idea/qaplug_profiles.xml generated Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AnalysisProjectProfileManager">
<option name="PROJECT_PROFILE" value="Project Default" />
<option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
<scopes />
<profiles>
<profile profile_name="Project Default" version="1.0" is_locked="false" />
</profiles>
<list size="0" />
</component>
</project>

109
README.md Normal file
View File

@ -0,0 +1,109 @@
# koTime
#### 介绍
koTime是一个springboot项目性能分析工具通过追踪方法调用链路以及对应的运行时长快速定位性能瓶颈
优点:
> * 无缝集成springboot使用简单
> * 通过简单配置集成,与业务逻辑无耦合
缺点:
> * 目前仅适用于单机版,不支持分布式和集群
#### 安装教程
1. 引入依赖 或者 下载发行版本
```
<dependency>
<groupId>cn.langpy</groupId>
<artifactId>simsearch</artifactId>
<version>1.2</version>
</dependency>
```
2. 配置信息
在application.yml中配置
```
sim-search.dir=xxx //索引位置可不填使用默认位置当前项目下的indexs目录第一次运行需手动创建
sim-search.size.core=10 //创建索引的核心线程数量根据cpu自行决定可不填默认为10
sim-search.size.max=10 //创建索引的最大线程数量根据cpu自行决定可不填默认为200
sim-search.size.queue=1000 //创建索引的线程队列容量自行决定可不填默认为20000
sim-search.index.init=true 重启时是否要对之前的索引进行删除默认为false
```
#### 使用说明
1. 在需要创建索引的实体上标注需要创建索引的字段
```java
import cn.langpy.simsearch.annotation.IndexColumn;
import cn.langpy.simsearch.annotation.IndexId;
public class Student {
/*索引唯一id*/
@IndexId
private String id;
/*需要创建索引的字段*/
@IndexColumn
private String studentName;
@IndexColumn
private String schoolName;
private String age;
}
```
2. 在需要创建索引的方法上加上创建索引的注解
```java
```
3. 在需要删除索引的方法上加上删除索引的注解
```java
```
4. 搜索的时候自定义一个空的方法,加上注解即可
```java
```
注意:搜索结果仅仅是搜索出加上@IndexId和@IndexColumn的字段,具体内容自行往业务数据库查询
#### 版本说明
1.接口列表总览
在列表中会显示该接口的运行耗时,如果为绿色则无需优化,如果为红色,需要详细查看问题所在
![输入图片说明](https://images.gitee.com/uploads/images/2020/1209/232411_3e487b47_1625471.png "屏幕截图.png")
2.调用详情
点开接口时,会显示该接口的调用链路以及运行时长
![输入图片说明](https://images.gitee.com/uploads/images/2020/1209/232636_4ec0556c_1625471.png "屏幕截图.png")
#### 版本说明
> V1.0-snapshots提供基础索引创建、删除和检索功能
> V1.1:增加重启索引初始化功能
> V1.2:搜索时,如果未找到搜索,可走默认模式
#### 问题说明
1. 本项目中使用了aspectjweaver依赖如果引入的项目中没有该依赖自行引入
```
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>xxx</version>
</dependency>
```

2
ko-time.iml Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4" />

130
pom.xml Normal file
View File

@ -0,0 +1,130 @@
<?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>
<groupId>org.example</groupId>
<artifactId>koTime</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.7.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.11.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.3.1.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.36</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,12 @@
package cn.langpy.kotime.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ComputeTime {
String value() default "chinese";
}

View File

@ -0,0 +1,7 @@
package cn.langpy.kotime.config;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan("cn.langpy.kotime")
public class LoadConfig {
}

View File

@ -0,0 +1,35 @@
package cn.langpy.kotime.controller;
import cn.langpy.kotime.model.RunTimeNode;
import cn.langpy.kotime.model.SystemStatistic;
import cn.langpy.kotime.util.Context;
import cn.langpy.kotime.util.MethodType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@Controller
@RequestMapping("/koTime")
@Slf4j
public class KoTimeController {
@GetMapping
public String index(Model model, HttpServletRequest request) {
List<RunTimeNode> list = Context.get(MethodType.Controller);
model.addAttribute("list",list);
SystemStatistic system = Context.getStatistic();
model.addAttribute("system",system);
return "index";
}
@GetMapping("/getTree")
@ResponseBody
public RunTimeNode getTree(String methodName,Model model, HttpServletRequest request) {
return Context.getTree(methodName);
}
}

View File

@ -0,0 +1,37 @@
package cn.langpy.kotime.handler;
import cn.langpy.kotime.annotation.ComputeTime;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
@Slf4j
@Aspect
@Component
public class ComputeTimeHandler {
@Pointcut("@annotation(cn.langpy.kotime.annotation.ComputeTime)")
public void preProcess(){
}
@Around("preProcess()")
public Object doAroundCompute(ProceedingJoinPoint pjp) throws Throwable{
ComputeTime computeTime = ((MethodSignature)pjp.getSignature()).getMethod().getAnnotation(ComputeTime.class);
long begin = System.nanoTime();
Object obj=pjp.proceed();
long end =System.nanoTime();
if ("chinese".equals(computeTime.value())) {
log.info("调用方法={},耗时={}毫秒",pjp.getTarget().getClass().getName()+"."+pjp.getSignature().getName(),(end-begin)/1000000);
}else{
log.info("method={},runTime={}ms",pjp.getTarget().getClass().getName()+"."+pjp.getSignature().getName(),(end-begin)/1000000);
}
return obj;
}
}

View File

@ -0,0 +1,30 @@
package cn.langpy.kotime.handler;
import cn.langpy.kotime.model.RunTimeNode;
import cn.langpy.kotime.util.Common;
import cn.langpy.kotime.util.Context;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public interface ComputeTimeHandlerInterface {
@Pointcut("")
void prog();
@Around("prog()")
default Object globalCompute(ProceedingJoinPoint pjp) throws Throwable{
long begin = System.nanoTime();
Object obj=pjp.proceed();
long end =System.nanoTime();
String packName = this.getClass().getPackage().getName();
RunTimeNode parent = Common.getParentRunTimeNode(packName);
RunTimeNode current = Common.getCurrentRunTimeNode(pjp,((end-begin)/1000000.0));
Context.set(parent,current);
return obj;
}
}

View File

@ -0,0 +1,120 @@
package cn.langpy.kotime.model;
import cn.langpy.kotime.util.MethodType;
import java.util.List;
import java.util.Objects;
public class RunTimeNode implements Comparable<RunTimeNode> {
private String name;
private String className;
private String methodName;
private Double avgRunTime = 0.0;
private Double value = 0.0;
private String avgRunTimeUnit = "ms";
private MethodType methodType;
private List<RunTimeNode> children;
@Override
public int compareTo(RunTimeNode ob) {
return this.avgRunTime.compareTo(ob.getAvgRunTime());
}
public Double getValue() {
return value;
}
public void setValue(Double value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAvgRunTimeUnit() {
return avgRunTimeUnit;
}
public void setAvgRunTimeUnit(String avgRunTimeUnit) {
this.avgRunTimeUnit = avgRunTimeUnit;
}
public MethodType getMethodType() {
return methodType;
}
public void setMethodType(MethodType methodType) {
this.methodType = methodType;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Double getAvgRunTime() {
return avgRunTime;
}
public void setAvgRunTime(Double avgRunTime) {
this.avgRunTime = avgRunTime;
}
public List<RunTimeNode> getChildren() {
return children;
}
public void setChildren(List<RunTimeNode> children) {
this.children = children;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RunTimeNode that = (RunTimeNode) o;
return Objects.equals(className, that.className) &&
Objects.equals(methodName, that.methodName);
}
@Override
public int hashCode() {
return Objects.hash(className, methodName);
}
@Override
public String toString() {
return "RunTimeNode{" +
"className='" + className + '\'' +
", methodName='" + methodName + '\'' +
", avgRunTime=" + avgRunTime +
", avgRunTimeUnit='" + avgRunTimeUnit + '\'' +
", methodType=" + methodType +
", children=" + children +
'}';
}
}

View File

@ -0,0 +1,68 @@
package cn.langpy.kotime.model;
public class SystemStatistic {
private String name;
private Double avgRunTime = 0.0;
private Double maxRunTime = 0.0;
private Double minRunTime = 0.0;
private Integer totalNum;
private Integer delayNum;
private Integer normalNum;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getAvgRunTime() {
return avgRunTime;
}
public void setAvgRunTime(Double avgRunTime) {
this.avgRunTime = avgRunTime;
}
public Double getMaxRunTime() {
return maxRunTime;
}
public void setMaxRunTime(Double maxRunTime) {
this.maxRunTime = maxRunTime;
}
public Double getMinRunTime() {
return minRunTime;
}
public void setMinRunTime(Double minRunTime) {
this.minRunTime = minRunTime;
}
public Integer getTotalNum() {
return totalNum;
}
public void setTotalNum(Integer totalNum) {
this.totalNum = totalNum;
}
public Integer getDelayNum() {
return delayNum;
}
public void setDelayNum(Integer delayNum) {
this.delayNum = delayNum;
}
public Integer getNormalNum() {
return normalNum;
}
public void setNormalNum(Integer normalNum) {
this.normalNum = normalNum;
}
}

View File

@ -0,0 +1,91 @@
package cn.langpy.kotime.util;
import cn.langpy.kotime.model.RunTimeNode;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
public class Common {
public static RunTimeNode getParentRunTimeNode(String packName) {
String parentClassName = "";
String parentMothodName = "";
StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
String[] packNameSplit = packName.split("\\.");
String filter = packNameSplit.length>1 ? packNameSplit[0]+"."+packNameSplit[1] : packNameSplit[0];
int stacksLength = stacks.length;
for (int i = 0; i < stacksLength; i++) {
StackTraceElement stack = stacks[i];
if (stack.getClassName().startsWith(filter)&& !stack.getClassName().contains("$")) {
parentClassName = stack.getClassName();
parentMothodName = stack.getMethodName();
break;
}
}
RunTimeNode parent = new RunTimeNode();
parent.setClassName(parentClassName);
parent.setMethodName(parentMothodName);
parent.setName(parentClassName.substring(parentClassName.lastIndexOf(".")+1)+"."+parentMothodName);
parent.setMethodType(getMethodType(parentClassName));
parent.setChildren(new ArrayList<>());
return parent;
}
public static RunTimeNode getCurrentRunTimeNode(ProceedingJoinPoint pjp,Double runTime) {
String className = pjp.getTarget().getClass().getName();
String methodName = pjp.getSignature().getName();
RunTimeNode current = new RunTimeNode();
current.setName(className.substring(className.lastIndexOf(".")+1)+"."+methodName);
current.setClassName(className);
current.setMethodName(methodName);
current.setAvgRunTime(runTime);
current.setChildren(new ArrayList<>());
current.setMethodType(getMethodType(pjp));
return current;
}
public static MethodType getMethodType(ProceedingJoinPoint pjp) {
MethodType methodType = null;
Class<?> targetClass = pjp.getTarget().getClass();
if (targetClass.getAnnotation(Controller.class)!=null || targetClass.getAnnotation(RestController.class)!=null) {
methodType = MethodType.Controller;
}else if (targetClass.getAnnotation(Service.class)!=null) {
methodType = MethodType.Service;
}else if (targetClass.getAnnotation(Repository.class)!=null) {
methodType = MethodType.Dao;
}
if (methodType == null) {
String className = pjp.getTarget().getClass().getName().toLowerCase();
if (className.contains("controller")) {
methodType = MethodType.Controller;
}else if (className.contains("service")) {
methodType = MethodType.Service;
}else if (className.contains("dao") || className.contains("mapper")) {
methodType = MethodType.Dao;
}else{
methodType = MethodType.Others;
}
}
return methodType;
}
public static MethodType getMethodType(String className) {
MethodType methodType = null;
className = className.toLowerCase();
if (className.contains("controller")) {
methodType = MethodType.Controller;
}else if (className.contains("service")) {
methodType = MethodType.Service;
}else if (className.contains("dao") || className.contains("mapper")) {
methodType = MethodType.Dao;
}else{
methodType = MethodType.Others;
}
return methodType;
}
}

View File

@ -0,0 +1,112 @@
package cn.langpy.kotime.util;
import cn.langpy.kotime.model.RunTimeNode;
import cn.langpy.kotime.model.SystemStatistic;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
public class Context {
private static Map<String, RunTimeNode> runTimeNodeMap;
static {
runTimeNodeMap = new HashMap<>();
}
public static void set(RunTimeNode parent,RunTimeNode current) {
String parentKey = parent.getClassName()+"."+parent.getMethodName();
String currentKey = current.getClassName()+"."+current.getMethodName();
if (!currentKey.contains("$")) {
log.info("调用方法="+currentKey+",耗时="+current.getAvgRunTime()+"毫秒");
}else {
return;
}
if (".".equals(parentKey)) {
if (runTimeNodeMap.containsKey(currentKey)) {
runTimeNodeMap.get(currentKey).setAvgRunTime(current.getAvgRunTime());
}else{
runTimeNodeMap.put(currentKey,current);
}
}else if (runTimeNodeMap.containsKey(parentKey)) {
RunTimeNode hisRunTimeNode = runTimeNodeMap.get(parentKey);
List<RunTimeNode> hisRunTimeNodeChildren = hisRunTimeNode.getChildren();
if (hisRunTimeNodeChildren!=null) {
if (hisRunTimeNodeChildren.contains(current)) {
int hisLength = hisRunTimeNodeChildren.size();
for (int i = 0; i < hisLength; i++) {
if (hisRunTimeNodeChildren.get(i)==current) {
current.setAvgRunTime((current.getAvgRunTime()+hisRunTimeNode.getChildren().get(i).getAvgRunTime())/2.0);
hisRunTimeNodeChildren.set(i,current) ;
break;
}
}
}else{
hisRunTimeNodeChildren.add(current);
}
} else {
List<RunTimeNode> list = new ArrayList<>();
list.add(current);
hisRunTimeNode.setChildren(list);
}
runTimeNodeMap.put(parentKey,hisRunTimeNode);
}else{
List<RunTimeNode> list = new ArrayList<>();
list.add(current);
parent.setChildren(list);
runTimeNodeMap.put(parentKey,parent);
}
}
public static RunTimeNode get(String key) {
return runTimeNodeMap.get(key);
}
public static List<RunTimeNode> get(MethodType methodType) {
return runTimeNodeMap.values().stream()
.filter(runTimeNode -> runTimeNode.getMethodType()==methodType)
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
}
public static RunTimeNode getTree(String key) {
RunTimeNode root = runTimeNodeMap.get(key);
if (root==null) {
return root;
}
root.setValue(root.getAvgRunTime());
List<RunTimeNode> children = root.getChildren();
if (children!=null&&children.size()>0) {
children.forEach(child->{
String childKey = child.getClassName()+"."+child.getMethodName();
RunTimeNode newChild = getTree(childKey);
if (newChild!=null) {
child.setChildren(newChild.getChildren());
child.setValue(child.getAvgRunTime());
}
});
}
return root;
}
public static SystemStatistic getStatistic() {
List<RunTimeNode> controllerApis = get(MethodType.Controller);
SystemStatistic systemStatistic = new SystemStatistic();
int delayNum = (int)controllerApis.stream().filter(controllerApi -> controllerApi.getAvgRunTime() >= 800).count();
systemStatistic.setDelayNum(delayNum);
int normalNum = (int)controllerApis.stream().filter(controllerApi -> controllerApi.getAvgRunTime() < 800).count();
systemStatistic.setNormalNum(normalNum);
int totalNum = (int)controllerApis.stream().count();
systemStatistic.setTotalNum(totalNum);
Double max = controllerApis.stream().map(api->api.getAvgRunTime()).max(Double::compareTo).get();
Double min = controllerApis.stream().map(api->api.getAvgRunTime()).min(Double::compareTo).get();
Double avg = controllerApis.stream().map(api->api.getAvgRunTime()).collect(Collectors.averagingDouble(Double::doubleValue));
systemStatistic.setMaxRunTime(max);
systemStatistic.setMinRunTime(min);
systemStatistic.setAvgRunTime(avg);
return systemStatistic;
}
}

View File

@ -0,0 +1,8 @@
package cn.langpy.kotime.util;
public enum MethodType {
Controller,
Service,
Dao,
Others;
}

View File

@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.langpy.kotime.config.LoadConfig

View File

@ -0,0 +1,15 @@
spring:
mvc:
static-path-pattern: /static/**
freemarker:
allow-request-override: false
cache: true
check-template-location: true
charset: UTF-8
content-type: text/html
suffix: .html
template-loader-path: classpath:/templates
expose-request-attributes: false
expose-session-attributes: false
expose-spring-macro-helpers: false
request-context-attribute: ctx

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,464 @@
/**
layui官网
By 贤心
*/
h1,h2,h3{font-size: 14px;}
::-webkit-input-placeholder{color: #999}
/* 布局 */
.site-inline{font-size: 0;}
.site-tree, .site-content{display: inline-block; *display:inline; *zoom:1; vertical-align: top; font-size: 14px;}
.site-tree{width: 220px; min-height: 900px; padding: 5px 0 20px;}
.site-content{width: 899px; min-height: 900px; padding: 20px 0 10px 20px;}
/* 头部 */
.header{height: 59px; border-bottom: 1px solid #404553; background-color: #393D49;}
.logo{position: absolute; left: 0; top: 16px;}
.logo img{width: 82px; height: 31px;}
.header .layui-nav{position: absolute; right: 0; top: 0; padding: 0; background: none;}
.header .layui-nav .layui-nav-item{margin: 0 20px; }
.header .layui-nav .layui-nav-item[mobile]{display: none;}
.header .layui-container .logo{left: 15px;}
.header .layui-container .layui-nav{right: 15px;}
.header .layui-nav .layui-badge,
.header .layui-nav .layui-badge-dot{right: 0;}
.menu{position: absolute; right: 0; top: 0; line-height: 65px;}
.menu a{display:inline-block; *display:inline; *zoom:1; vertical-align:top;}
.menu a{position: relative; padding: 0 20px; margin: 0 20px; color: #c2c2c2; font-size: 14px;}
.menu a:hover{color: #fff; transition: all .5s; -webkit-transition: all .5s}
.menu a.this{color: #fff}
.menu a.this::after{content: ''; position: absolute; left: 0; bottom: -1px; width: 100%; height: 5px; background-color: #5FB878;}
.header-index{}
.header-index .site-banner-bg{}
.header-index[spring]{border: none; background-color: #0D1206}
.header-index[summer]{border: none; background-color: #0A0E11}
.header-index[autumn]{border: none; background-color: #100903}
.header-index[winter]{border: none; background-color: #110F25/*#06041C*/}
.header-demo{height: 60px; border-bottom: none;}
.header-demo .logo{left: 40px;}
.header-demo .layui-nav{top: 0;}
.header-demo .layui-nav .layui-nav-item{margin: 0 10px;}
.header-demo .layui-nav .layui-this a{padding: 0 30px;}
.component{position: absolute; width: 160px; left: 120px; top: 16px; }
.component .layui-input{height: 30px; padding-left: 12px; background-color: #424652; background-color: rgba(255,255,255,.05); border: none 0; color: #fff; color: rgba(255,255,255,.5); font-size: 12px;}
.component .layui-form-select .layui-edge{display: none; border-top-color: #999;}
.component .layui-form-select dl{top: 36px; background-color: rgba(255,255,255,.9)}
.header-demo .component{left: 185px;}
/* 子侧边 */
.layui-side-child{width: 160px!important; left: 200px; bottom: 60px!important; border-right: 1px solid #eee; background-color: #fff;}
.layui-side-child .layui-side-scroll{width: 170px;}
.layui-side-child .layui-nav{padding: 10px 0; width: 160px; border-radius: 0; background: none}
.layui-side-child .layui-nav-child{border-radius: 0;}
.layui-side-child .layui-nav .layui-nav-title a,
.layui-side-child .layui-nav .layui-nav-title a:hover,
.layui-side-child .layui-nav-itemed>a{color: #666 !important;}
.layui-side-child .layui-nav-itemed .layui-nav-child{margin-bottom: 10px; background: none !important;}
.layui-side-child .layui-nav .layui-nav-item a{height: 30px; line-height: 30px; color: #666;}
.layui-side-child .layui-nav .layui-nav-item a:hover{background: none !important;}
.layui-side-child .layui-nav .layui-nav-child a{color: #999 !important;}
.layui-side-child .layui-nav .layui-nav-more{display: none;}
.layui-side-child .layui-nav-tree .layui-this,
.layui-side-child .layui-nav-tree .layui-this>a,
.layui-side-child .layui-nav-tree .layui-nav-child dd.layui-this,
.layui-side-child .layui-nav-tree .layui-nav-child dd.layui-this a{background: none; color: #5FB878 !important;}
.layui-side-child .layui-nav .layui-nav-child a:hover{color: #009688 !important}
.layui-side-child .layui-nav-bar{background-color: #5FB878;}
/* 底部 */
.footer{padding: 30px 0; line-height: 30px; text-align: center; color: #666; font-weight: 300;}
body .layui-layout-admin .footer-demo{height: 50px; line-height: 50px; padding: 5px 0;}
.footer a{padding: 0 5px;}
.site-union{color: #999;}
.site-union>*{display: inline-block; vertical-align: middle;}
.site-union a[sponsor] img{width: 80px;}
.site-union span{position: relative; top: 5px;}
.site-union span a{padding: 0; display: inline; color: #999;}
.site-union span a:hover{text-decoration: underline;}
.site-union .site-union-desc{display: block; margin-bottom: 10px;}
.footer-demo p,
.footer-demo .site-union,
.footer-demo .site-union p{display: inline-block; vertical-align: middle; padding-right: 10px;}
.footer-demo .site-union{position: relative; top: -5px;}
.footer-demo .site-union .site-union-desc{margin-bottom: 0; padding-right: 0;}
.footer-demo .site-union a[sponsor] img{position: relative; top: 3px;}
/* 首页banner部分 */
.site-banner{position: relative; height: 600px; text-align: center; overflow: hidden; background-color: #393D49;}
.site-banner-bg
,.site-banner-main{position: absolute; left: 0; top: 0; width: 100%; height: 100%;}
.site-banner-bg{background-position: center 0;}
.site-zfj{padding-top: 25px; height: 220px;}
.site-zfj i{position: absolute; left: 50%; top: 50px; width: 200px; height: 200px; margin-left: -100px; font-size: 180px; color: #c2c2c2;}
@keyframes site-zfj {
0% {opacity: 1; transform: translate3d(0, 0, 0) rotate(0deg) scale(1);}
10% {opacity: 0.8; transform: translate3d(-100px, 0px, 0) rotate(10deg) scale(0.7);}
35% {opacity: 0.6; transform: translate3d(100px, 0px, 0) rotate(30deg) scale(0.4);}
50% {opacity: 0.4; transform: translate3d(0, 0, 0) rotate(360deg) scale(0);}
80% {opacity: 0.2; transform: translate3d(0, 0, 0) rotate(720deg) scale(1);}
90% {opacity: 0.1; transform: translate3d(0, 0, 0) rotate(3600deg) scale(6);}
100% {opacity: 1; transform: translate3d(0, 0, 0) rotate(3600deg) scale(1);}
}
@keyframes site-desc {
0% { transform: scale(1.1);}
100% {transform: scale(1);}
}
.site-zfj-anim i{-webkit-animation-name: site-zfj; animation-name: site-zfj; -webkit-animation-duration: 5s; animation-duration: 5s; -webkit-animation-timing-function: linear; animation-timing-function: linear;}
/* 描述字体 */
@font-face {font-family: 'webfont-desc';
src: url('//at.alicdn.com/t/webfont_eovt4pxxy5.eot'); /* IE9*/
src: url('//at.alicdn.com/t/webfont_eovt4pxxy5.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('//at.alicdn.com/t/webfont_eovt4pxxy5.woff') format('woff'), /* chrome、firefox */
url('//at.alicdn.com/t/webfont_eovt4pxxy5.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
url('//at.alicdn.com/t/webfont_eovt4pxxy5.svg#思源黑体-极细') format('svg'); /* iOS 4.1- */
}
.web-font-desc{
font-family:"webfont-desc" !important;
font-size:16px;font-style:normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.site-desc{position: relative; height: 70px; margin-top: 20px;}
.site-desc .web-font-desc{color: #fff; color: rgba(255,255,255,.8); font-size: 61px;}
.site-desc-anim{-webkit-animation-name: site-desc; animation-name: site-desc;}
.site-desc cite{position: absolute; bottom: -40px; left: 0; width: 100%; color: #c2c2c2; font-style: normal;}
.site-download{margin-top: 80px; font-size: 0;}
.site-download a{position: relative; padding: 0 55px 0 95px; height: 65px; line-height: 65px; border: 1px solid #c2c2c2; border-color: rgba(255,255,255,.2); font-size: 24px; color: #ccc; transition: all .5s; -webkit-transition: all .5s;}
.site-download a:hover{border-color: rgba(255,255,255,.3); color: #fff; background-color: rgba(255,255,255,.05); border-radius: 30px;}
.site-download a cite{position: absolute; left: 55px; top: 2px; font-size: 30px;}
.site-version{position: relative; margin-top: 15px; color: #ccc; font-size: 12px;}
.site-version span{padding: 0 3px;}
.site-version *{font-style: normal;}
.site-version a{color: #e2e2e2; text-decoration: underline;}
.site-banner-other{position: absolute; left: 0; bottom: 35px; width: 100%; text-align: center; font-size: 0;}
.site-banner-other iframe{border: none;}
.site-banner-other a{display: inline-block; vertical-align: middle; height: 28px; line-height: 28px; margin: 0 6px; padding: 0 10px; border-radius: 2px; color: #c2c2c2; color: rgba(255,255,255,.8); border: 1px solid #c2c2c2; border-color: rgba(255,255,255,.2); font-size: 14px; transition: all .5s; -webkit-transition: all .5s;}
.site-banner-other a:hover{color: #fff; background-color: rgba(255,255,255,.1);}
.site-idea{margin: 50px 0; font-size: 0; text-align: center; font-weight: 300;}
.site-idea li{display: inline-block; vertical-align: top; *display: inline; *zoom:1; font-size: 14px; }
.site-idea li{width: 298px; height: 150px; padding: 30px; line-height: 24px; margin-left: 30px; border: 1px solid #d2d2d2; text-align: left;}
.site-idea li:first-child{margin-left: 0}
.site-idea .layui-field-title{border-color: #d2d2d2}
.site-idea .layui-field-title legend{margin: 0 20px 20px 0; padding: 0 20px; text-align: center;}
/* 赞助商 */
.site-sponsor-home{margin-top: 40px; text-align: center;}
.site-sponsor-home .layui-btn{position: relative; width: 248px; height: 60px; line-height: 60px; background: none; border-color: #212121; font-size: 20px; border-radius: 6px;}
.site-sponsor-home .layui-btn:hover{background: #4A4855; color: #BAB8C3;}
.site-sponsor-home p{position: relative; padding-top: 15px; font-size: 22px; color: #212121;}
.site-sponsor-home p:before{content: ''; position: relative; top: -2px; display: inline-block; vertical-align: middle; width: 30px; height: 30px; margin-right: 10px; background: url(http://cdn.layui.com/upload/2018_1/168_1514869467160_26113.png) center; background-repeat: no-repeat; background-size: contain;}
@media screen and (max-width: 750px) {
.site-sponsor-home .layui-btn{width: 180px; height: 45px; line-height: 45px; font-size: 20px;}
.site-sponsor-home p{font-size: 16px;}
.site-sponsor-home p:before{width: 20px; height: 20px;}
}
/* 辅助 */
.site-tips{margin-bottom: 10px; padding: 15px; line-height: 22px; border-left: 5px solid #0078AD; background-color: #f2f2f2;}
body .site-tips p{margin: 0;}
body .layui-layer-notice .layui-layer-content{padding: 20px; line-height: 26px; background-color: #393D49; color: #fff; font-weight: 300;}
.layui-layer-notice .layui-text{color: #f8f8f8;}
.layui-layer-notice .layui-text a{color: #009688;}
/* 目录 */
.site-dir{display: none;}
.site-dir li{line-height: 26px; margin-left: 20px; overflow: visible; list-style-type: disc;}
.site-dir li a{display: block;}
.site-dir li a:active{color: #01AAED;}
.site-dir li a.layui-this{color: #01AAED;}
body .layui-layer-dir{box-shadow: none; border: 1px solid #d2d2d2;}
body .layui-layer-dir .layui-layer-content{padding: 10px;}
.site-dir a em{padding-left: 5px; font-size: 12px; color: #c2c2c2; font-style: normal;}
/* 文档 */
.site-tree{border-right: 1px solid #eee; }
.site-tree .layui-tree{line-height: 32px;}
.site-tree .layui-tree li i{position: relative; font-size: 22px; color: #000}
.site-tree .layui-tree li a cite{padding: 0 8px;}
.site-tree .layui-tree .site-tree-noicon a cite{padding-left: 15px;}
.site-tree .layui-tree li a em{font-size: 12px; color: #bbb; padding-right: 5px; font-style: normal;}
.site-tree .layui-tree li h2{line-height: 36px; border-left: 5px solid #009E94; margin: 15px 0 5px; padding: 0 10px; background-color: #f2f2f2;}
.site-tree .layui-tree li ul{margin-left: 27px; line-height: 28px;}
.site-tree .layui-tree li ul a,
.site-tree .layui-tree li ul a i{color: #777;}
.site-tree .layui-tree li ul a:hover{color: #333;}
.site-tree .layui-tree li ul li{margin-left: 25px; overflow: visible; list-style-type: disc; /*list-style-position: inside;*/}
.site-tree .layui-tree li ul li cite,
.site-tree .layui-tree .site-tree-noicon ul li cite{padding-left: 0;}
.site-tree .layui-tree .layui-this a{color: #01AAED;}
.site-tree .layui-tree .layui-this .layui-icon{color: #01AAED;}
.site-fix .site-tree{position: fixed; top: 0; bottom: 0; z-index: 666; min-height: 0; overflow: auto; background-color: #fff;}
.site-fix .site-content{margin-left: 220px;}
.site-fix-footer .site-tree{/*margin-bottom: 120px;*/}
.site-title{ margin: 30px 0 20px;}
.site-title fieldset{border: none; padding: 0; border-top: 1px solid #eee;}
.site-title fieldset legend{margin-left: 20px; padding: 0 10px; font-size: 22px; font-weight: 300;}
.site-text a{color: #01AAED;}
.site-h1{margin-bottom: 20px; line-height: 60px; padding-bottom: 10px; color: #393D49; border-bottom: 1px solid #eee; font-size: 28px; font-weight: 300;}
.site-h1 .layui-icon{position: relative; top: 5px; font-size: 35px; margin-right: 10px;}
.site-text{position:relative;}
.site-text p{margin-bottom: 10px; line-height:22px;}
.site-text em{padding: 0 3px; font-weight: 500; font-style: italic; color: #666;}
.site-text code{margin:0 5px; padding: 3px 10px; border: 1px solid #e2e2e2; background-color: #fbfbfb; color: #666; border-radius: 2px;}
.site-table{width: 100%; margin: 10px 0;}
.site-table thead{background-color:#f2f2f2; }
.site-table th,
.site-table td{padding: 6px 15px; min-height: 20px; line-height: 20px; border:1px solid #ddd; font-size: 14px; font-weight: 400;}
.site-table tr:nth-child(even){background: #fbfbfb;}
.site-block{padding: 20px; border: 1px solid #eee;}
.site-block .layui-form{margin-right: 200px;}
/* 更新日志 */
.site-changelog .layui-timeline-title h2{display: inline-block;}
.site-changelog .layui-timeline-title .layui-badge-rim{top: -2px; left: 10px;}
/* 颜色 */
.site-doc-color{font-size: 0;}
.site-doc-color li{display: inline-block; vertical-align: middle; width: 180px; margin-left: 20px; margin-bottom: 20px; padding: 20px 10px; color: #fff; text-align: center; border-radius: 2px; line-height: 22px; font-size: 14px;}
.site-doc-color li p[tips]{opacity: 0.8; font-size: 12px;}
.site-doc-necolor li{width: 108px; margin-top: 15px; margin-left: 0; border-radius: 0;}
.site-doc-bgcolor li{padding: 10px;}
/* 宫格 */
.site-doc-icon{margin-bottom: 50px; font-size: 0;}
.site-doc-icon li{display: inline-block; vertical-align: middle; width: 127px; height: 105px; line-height: 25px; padding: 20px 0; margin-right: -1px; margin-bottom: -1px; border: 1px solid #e2e2e2; font-size: 14px; text-align: center; color: #666; transition: all .3s; -webkit-transition: all .3s;}
.site-doc-anim li{height: auto;}
.site-doc-icon li .layui-icon{display: inline-block; font-size: 36px;}
.site-doc-icon li .doc-icon-name,
.site-doc-icon li .doc-icon-code{color: #c2c2c2;}
.site-doc-icon li .doc-icon-fontclass{height: 40px; line-height: 20px; padding: 0 5px; font-size: 13px; color: #333; }
.site-doc-icon li:hover{background-color: #f2f2f2; color: #000;}
/* 栅格示例 */
.grid-demo{padding: 10px; line-height: 50px; text-align: center; background-color: #79C48C; color: #fff;}
.grid-demo-bg1{background-color: #63BA79;}
.grid-demo-bg2{background-color: #49A761;}
.grid-demo-bg3{background-color: #38814A;}
/* 演示 */
body .layui-layout-admin .site-demo{bottom: 60px; padding: 0;}
body .site-demo-nav .layui-nav-item{line-height: 40px}
.layui-nav-item .layui-icon{position: relative; font-size: 20px;}
.layui-nav-item a cite{padding: 0 10px;}
.site-demo .layui-main{margin: 15px; line-height: 22px;}
.site-demo-editor{position: absolute; top: 0; bottom: 0; left: 0; width: 50%; }
.site-demo-area{position: absolute; top: 0; bottom: 0; width: 100%;}
.site-demo-editor textarea{position: absolute; width: 100%; height: 100%; padding: 10px; border: none; resize: none; background-color: #F7FBFF; background-color: #13151A; color: #999; font-family: Courier New; font-size: 12px; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}
.site-demo-btn{position: absolute; bottom: 15px; right: 20px;}
.site-demo-zanzhu{position: absolute; bottom: 0; left: 0; width: 100%; height: 90px; text-align: center; background-color: #e2e2e2; overflow: hidden;}
.site-demo-zanzhu>*{position: relative; z-index: 1;}
.site-demo-zanzhu:before{content: ""; position: absolute; z-index: 0; top: 50%; left: 50%; width: 120px; margin: -10px 0px 0px -60px; text-align: center; color: rgb(170, 170, 170); font-size: 18px; font-weight: 300; }
.site-demo-result{position: absolute; right: 0; top: 0; bottom: 0; width: 50%;}
.site-demo-result iframe{position: absolute; width: 100%; height: 100%;}
.site-demo-button{margin-bottom: 30px;}
.site-demo-button div{margin: 20px 30px 10px;}
.site-demo-button .layui-btn+.layui-btn{margin-left: 0;}
.site-demo-button .layui-btn{margin: 0 7px 10px 0; }
.site-demo-text a{color: #01AAED;}
.site-demo-laytpl{text-align: center;}
.site-demo-laytpl textarea,
.site-demo-laytpl div span{width: 40%; padding: 15px; margin: 0 15px;}
.site-demo-laytpl textarea{height: 300px; border: none; background-color: #3F3F3F; color: #E3CEAB; font-family: Courier New; resize: none;}
.site-demo-laytpl div span{display: inline-block; text-align: center; background: #101010; color: #fff;}
.site-demo-tplres{margin: 10px 0; text-align: center}
.site-demo-tplres .site-demo-tplh2,
.site-demo-tplres .site-demo-tplview{display: inline-block; width: 50%;}
.site-demo-tplres h2{padding: 15px; background: #e2e2e2;}
.site-demo-tplres h3{font-weight: 700;}
.site-demo-tplres div{padding: 14px; border: 1px solid #e2e2e2; text-align: left;}
.site-demo-upload,
.site-demo-upload img{width: 200px; height: 200px; border-radius: 100%;}
.site-demo-upload{position: relative; background: #e2e2e2;}
.site-demo-upload .site-demo-upbar{position: absolute; top: 50%; left: 50%; margin: -18px 0 0 -56px;}
.site-demo-upload .layui-upload-button{background-color: rgba(0,0,0,.2); color: rgba(255,255,255,1);}
.site-demo-util{position: relative; width: 300px;}
.site-demo-util img{width: 300px; border-radius: 100%;}
.site-demo-util span{position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: #333; cursor: pointer;}
@-webkit-keyframes demo-fengjie {
0% {-webkit-filter: blur(0); opacity: 1; background: #fff; height: 300px; border-radius: 100%;}
80% {-webkit-filter: blur(50px); opacity: 0.95;}
100% {-webkit-filter: blur(20px); opacity: 0; background: #fff;}
}
@keyframes demo-fengjie {
0% {filter: blur(0); opacity: 1; background: #fff; height: 300px; border-radius: 100%;}
80% {filter: blur(50px); opacity: 0.95;}
100% {filter: blur(20px); opacity: 0; background: #fff;}
}
.site-demo-fengjie{-webkit-animation-name: demo-fengjie; animation-name: demo-fengjie; -webkit-animation-duration: 5s; animation-duration: 5s;}
.layui-layout-admin .site-demo-body{top: 106px;}
.site-demo-title{position: fixed; left: 200px; right: 0; top: 65px;}
.site-demo-code{position: absolute; left: 0; top: 0; width: 100%; height: 100%; border: none; padding: 10px; resize: none; font-size: 12px; background-color: #F7FBFF; color: #881280; font-family: Courier New;}
.site-demo-overflow{overflow: hidden;}
/* 其它 */
#trans-tooltip,
#tip-arrow-bottom,
#tip-arrow-top{display: none !important;}
/* 独立组件 与 主页 */
.alone{text-align: center; background-color: #009688; color: #fff; font-weight: 300; transition: all .3s; -webkit-transition: all .3s;}
.alone:hover{background-color: #5FB878;}
.alone a{display: block; padding: 50px 20px; color: #fff; font-size: 30px;}
.alone a cite{display: block; padding-top: 10px; font-size: 14px;}
.alone-banner{height: 190px; text-align: center; font-weight: 300; background-color: #009688; color:#fff;}
.alone-banner h1{padding-top: 60px; line-height: 32px; font-size: 30px; font-weight: 300;}
.alone-banner p{padding-top: 20px; color: #e2e2e2; color: rgba(255,255,255,.8);}
.alone-nav .layui-tab-title li{margin-right: 30px; padding: 0; color: #666;}
.alone-nav .layui-tab-title li a{ padding: 0 20px;}
.alone-download{margin: 30px 0;}
.alone-download .layui-btn{margin-right: 10px;}
.alone-download span{display: inline-block; line-height: 44px; padding-right: 20px;}
.alone-download span em{color: #999;}
.alone-title{margin-top: 20px;}
.alone-download-btn{text-align: center; margin-top: 50px; font-size: 0;}
.alone-download-btn .layui-btn{position: relative; width: 206px; height: 60px; line-height: 60px; font-size: 26px; font-weight: 300;}
.alone-download-btn .layui-btn+.layui-btn{margin: 0;}
.alone-download-btn .alone-download-right{margin-left: 20px !important; border-color: #009688; background: none; color: #009688;}
.alone-download-btn .layui-btn img{position: relative; top: -3px; width: 118px;}
/* 适配多设备 */
@media screen and (max-width: 750px) {
.layui-main{width: auto; margin: 0 10px;}
.logo,
.header-demo .logo{left: 10px;}
.component{display: none}
.header .layui-nav-child{left: auto!important; right: 0!important;}
.site-demo-overflow{overflow: auto;}
.site-nav-layim{display: none !important;}
.header .layui-nav .layui-nav-item{margin: 0;}
.header .layui-nav .layui-nav-item a{padding: 0 20px;}
.header .layui-nav .layui-nav-item[pc]{display: none;}
.header .layui-nav .layui-nav-item[mobile]{display: inline-block;}
.site-banner{height: 300px;}
.site-banner-bg{background-size: cover;}
.site-zfj{height: 100px; padding-top: 5px;}
.site-zfj i{top: 10px; width: 100px; height: 100px; margin-left: -50px; font-size: 100px;}
.site-desc{background-size: 70%; margin: 0;}
.site-desc .web-font-desc{padding-top: 20px; font-size: 30px;}
.site-desc cite{display: none;}
.site-download{margin-top: 0; }
.site-download a{height: 40px; line-height: 40px; padding: 0 25px 0 60px; border-radius: 30px; color: #fff; font-size: 16px;}
.site-download a cite{left: 20px;}
.site-banner-other{bottom: 10px;}
.site-idea{margin: 20px 0;}
.site-idea li{margin: 0 0 20px 0; width: 100%; height: auto; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}
.site-hengfu img{max-width: 100%}
.site-block .layui-form{margin-right: 0;}
.layui-layer-dir{display: none;}
.site-tree{position: fixed; top: 0; bottom: 0; min-height: 0; overflow: auto; z-index: 1000; left: -260px; background-color: #fff; transition: all .3s; -webkit-transition: all .3s;}
.site-content{width: 100%; padding: 0; overflow: auto;}
.site-content img{max-width: 100%;}
.site-tree-mobile{display: block!important; position: fixed; z-index: 100000; bottom: 15px; left: 15px; width: 50px; height: 50px; line-height: 50px; border-radius: 2px; text-align: center; background-color: rgba(0,0,0,.7); color: #fff;}
.site-home .site-tree-mobile{display: none!important;}
.site-mobile .site-tree-mobile{display: none !important;}
.site-mobile .site-tree{left: 0;}
.site-mobile .site-mobile-shade{content: ''; position: fixed; top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(0,0,0,.8); z-index: 999;}
.site-tree-mobile i{font-size: 20px;}
.layui-code-view{-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;}
.layui-layout-admin .layui-side{position: fixed; top: 0; left: -260px; transition: all .3s; -webkit-transition: all .3s; z-index: 10000;}
.layui-body{position: static; bottom: 0; left: 0;}
.site-mobile .layui-side{left: 0;}
.site-mobile .layui-side-child{top: 50%; left: 200px; height: 300px; margin-top: -100px;}
body .layui-layout-admin .footer-demo{position: static; height: auto; padding: 15px 0; line-height: 30px;}
.footer-demo p,
.footer-demo .site-union{height: auto; padding-right: 0;}
.footer-demo .site-union{top: 0;}
.footer-demo .site-union span{top:0 ;}
.site-demo-area,
.site-demo-editor,
.site-demo-result,
.site-demo-editor textarea,
.site-demo-result iframe{position: static; width: 100%;}
.site-demo-editor textarea{height: 350px;}
.site-demo-zanzhu{display: none;}
.site-demo-btn{bottom: auto; top: 370px;}
.site-demo-result iframe{height: 500px;}
.site-demo-laytpl textarea, .site-demo-laytpl div span{margin: 0;}
.site-demo-tplres .site-demo-tplh2, .site-demo-tplres .site-demo-tplview{width: 100%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;}
.site-demo-title{position: static; left: 0;}
body .layui-layout-admin .site-demo{position: static;}
.site-demo-code{position: static; height: 350px;}
}
@-webkit-keyframes site-anim-closeup{ /* 特写 */
from {-webkit-transform: translate3d(0, 0, 0) scale(1); opacity: 1;}
to { -webkit-transform: translate3d(0, 400px, 0) scale(2); opacity: 0.5;}
}
@keyframes site-anim-closeup{
from {transform: translate3d(0, 0, 0) scale(1); opacity: 1;}
to {transform: translate3d(0, 400px, 0) scale(2); opacity: 0.5;}
}
.site-out-up{-webkit-animation-duration: 3s; animation-duration: 3s; -webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation-name: site-anim-closeup; animation-name: site-anim-closeup; overflow: hidden;}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
/** layui-v2.5.7 MIT License */
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Some files were not shown because too many files have changed in this diff Show More