parent
be805155e1
commit
447b3a2450
@ -0,0 +1,187 @@
|
|||||||
|
<?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.1.2.RELEASE</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
<groupId>xyz.wbsite</groupId>
|
||||||
|
<artifactId>FILEMGR-WEB</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<!--<packaging>war</packaging>--><!--需要打包成war时放开-->
|
||||||
|
<name>FILEMGR-WEB</name>
|
||||||
|
<description>project for Spring Boot</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<maven.test.skip>true</maven.test.skip>
|
||||||
|
<commons-io-version>2.6</commons-io-version>
|
||||||
|
<pagehelper-version>1.2.5</pagehelper-version>
|
||||||
|
<mybatis-version>1.3.2</mybatis-version>
|
||||||
|
<dozer-version>5.5.1</dozer-version>
|
||||||
|
<spring-cloud.version>Greenwich.RC2</spring-cloud.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mybatis.spring.boot</groupId>
|
||||||
|
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- freemarker -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.sf.dozer</groupId>
|
||||||
|
<artifactId>dozer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
|
<version>${spring-cloud.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.pagehelper</groupId>
|
||||||
|
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||||
|
<version>${pagehelper-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mybatis.spring.boot</groupId>
|
||||||
|
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||||
|
<version>${mybatis-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.sf.dozer</groupId>
|
||||||
|
<artifactId>dozer</artifactId>
|
||||||
|
<version>${dozer-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>${commons-io-version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<!-- 项目名称 -->
|
||||||
|
<finalName>${artifactId}-${version}</finalName>
|
||||||
|
<!-- 默认的主代码目录 -->
|
||||||
|
<sourceDirectory>src/main/java</sourceDirectory>
|
||||||
|
<!-- 默认的测试代码目录 -->
|
||||||
|
<testSourceDirectory>src/test/java</testSourceDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
</resource>
|
||||||
|
<!-- 包含java下的xml文件 -->
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/java</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**/mpr/*.xml</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
<!-- 包含lib中所有jar包 -->
|
||||||
|
<resource>
|
||||||
|
<directory>${basedir}/src/main/resources/lib</directory>
|
||||||
|
<targetPath>BOOT-INF/lib/</targetPath>
|
||||||
|
<includes>
|
||||||
|
<include>*.jar</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
<!-- 启动bat -->
|
||||||
|
<resource>
|
||||||
|
<directory>${basedir}/src/main/resources</directory>
|
||||||
|
<includes>
|
||||||
|
<include>*.bat</include>
|
||||||
|
</includes>
|
||||||
|
<targetPath>${basedir}/target</targetPath>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
<compilerArguments>
|
||||||
|
<extdirs>${project.basedir}/src/main/resources/lib</extdirs>
|
||||||
|
</compilerArguments>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<webResources>
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}/src/main/resources/lib</directory>
|
||||||
|
<targetPath>WEB-INF/lib</targetPath>
|
||||||
|
<includes>
|
||||||
|
<include>*.jar</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</webResources>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>spring-milestones</id>
|
||||||
|
<name>Spring Milestones</name>
|
||||||
|
<url>https://repo.spring.io/milestone</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package xyz.wbsite;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)
|
||||||
|
public class Application extends SpringBootServletInitializer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||||
|
return application.sources(Application.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Application.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package xyz.wbsite.action.control;
|
||||||
|
|
||||||
|
import xyz.wbsite.framework.base.Control;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
public class Footer extends Control {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exec(Model model, HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package xyz.wbsite.action.control;
|
||||||
|
|
||||||
|
import xyz.wbsite.framework.base.Control;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
public class Header extends Control {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exec(Model model, HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package xyz.wbsite.action.screen;
|
||||||
|
|
||||||
|
import xyz.wbsite.framework.base.Screen;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
public class Index extends Screen {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exec(Model model, HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
|
||||||
|
model.addAttribute("hello", "Hello world!!!");
|
||||||
|
model.addAttribute("status", 0);
|
||||||
|
|
||||||
|
ArrayList<String> citys = new ArrayList<>();
|
||||||
|
citys.add("北京");
|
||||||
|
citys.add("上海");
|
||||||
|
citys.add("深圳");
|
||||||
|
model.addAttribute("citys", citys);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,98 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base - 基类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class BaseEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 行版本
|
||||||
|
*/
|
||||||
|
private long rowVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建用户
|
||||||
|
*/
|
||||||
|
@JsonIgnore
|
||||||
|
private long createBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JsonIgnore
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最后更新用户
|
||||||
|
*/
|
||||||
|
@JsonIgnore
|
||||||
|
private long lastUpdateBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最后更新时间
|
||||||
|
*/
|
||||||
|
@JsonIgnore
|
||||||
|
private Date lastUpdateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否删除
|
||||||
|
*/
|
||||||
|
@JsonIgnore
|
||||||
|
private boolean isDeleted;
|
||||||
|
|
||||||
|
public boolean getIsDeleted() {
|
||||||
|
return isDeleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsDeleted(boolean isDeleted) {
|
||||||
|
this.isDeleted = isDeleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRowVersion() {
|
||||||
|
return rowVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRowVersion(long rowVersion) {
|
||||||
|
this.rowVersion = rowVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCreateBy() {
|
||||||
|
return createBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateBy(long createBy) {
|
||||||
|
this.createBy = createBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastUpdateBy() {
|
||||||
|
return lastUpdateBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastUpdateBy(long lastUpdateBy) {
|
||||||
|
this.lastUpdateBy = lastUpdateBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreateTime() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime(Date createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLastUpdateTime() {
|
||||||
|
return lastUpdateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastUpdateTime(Date lastUpdateTime) {
|
||||||
|
this.lastUpdateTime = lastUpdateTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseFindRequest - 基类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class BaseFindRequest extends BaseGetAllRequest {
|
||||||
|
private int pageNumber = 1;
|
||||||
|
private int pageSize = 10;
|
||||||
|
private int beginIndex = 0;
|
||||||
|
private int endIndex = 10;
|
||||||
|
|
||||||
|
public int getPageNumber() {
|
||||||
|
return pageNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPageNumber(int pageNumber) {
|
||||||
|
this.pageNumber = pageNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPageSize() {
|
||||||
|
return pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPageSize(int pageSize) {
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBeginIndex() {
|
||||||
|
beginIndex = pageSize * (pageNumber - 1);
|
||||||
|
return beginIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBeginIndex(int beginIndex) {
|
||||||
|
this.beginIndex = beginIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEndIndex() {
|
||||||
|
endIndex = pageSize * (pageNumber - 1) + pageSize;
|
||||||
|
return endIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndIndex(int endIndex) {
|
||||||
|
this.endIndex = endIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePageNumber(int totalCount){
|
||||||
|
int maxPage = totalCount / pageSize + (totalCount % pageSize > 0 ? 1 : 0);
|
||||||
|
|
||||||
|
if (pageNumber > maxPage){
|
||||||
|
pageNumber = maxPage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseFindResponse - 基类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class BaseFindResponse<T> extends BaseResponse{
|
||||||
|
|
||||||
|
private List<T> result;
|
||||||
|
|
||||||
|
private Long totalCount;
|
||||||
|
|
||||||
|
public List<T> getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResult(List<T> result) {
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTotalCount() {
|
||||||
|
return totalCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalCount(Long totalCount) {
|
||||||
|
this.totalCount = totalCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseFindRequest - 基类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class BaseGetAllRequest extends BaseRequest {
|
||||||
|
|
||||||
|
private String sortKey;
|
||||||
|
|
||||||
|
private SortType sortType;
|
||||||
|
|
||||||
|
public String getSortKey() {
|
||||||
|
return sortKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSortKey(String sortKey) {
|
||||||
|
this.sortKey = sortKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SortType getSortType() {
|
||||||
|
return sortType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSortType(SortType sortType) {
|
||||||
|
this.sortType = sortType;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseRequest - 基类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class BaseRequest {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseSearchRequest - 基类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class BaseSearchRequest extends BaseFindRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模糊查询的关键字。
|
||||||
|
*/
|
||||||
|
private String keyword;
|
||||||
|
|
||||||
|
public String getKeyword() {
|
||||||
|
return keyword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeyword(String keyword) {
|
||||||
|
this.keyword = keyword;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseUpdateRequest - 基类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class BaseUpdateRequest extends BaseRequest{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本戳
|
||||||
|
*/
|
||||||
|
private long rowVersion;
|
||||||
|
|
||||||
|
public long getRowVersion() {
|
||||||
|
return rowVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRowVersion(long rowVersion) {
|
||||||
|
this.rowVersion = rowVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
public abstract class Control {
|
||||||
|
public abstract void exec(Model model, HttpServletRequest request, HttpServletResponse response);
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error - 错误基类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class Error {
|
||||||
|
|
||||||
|
/*错误类型*/
|
||||||
|
private ErrorType type;
|
||||||
|
|
||||||
|
/*错误内容*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public Error() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Error(ErrorType type, String message) {
|
||||||
|
this.type = type;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ErrorType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(ErrorType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ErrorType - 错误类型
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public enum ErrorType {
|
||||||
|
BUSINESS_ERROR,
|
||||||
|
SYSTEM_ERROR,
|
||||||
|
UNKNOWN_ERROR,
|
||||||
|
UNIQUENESS_ERROR,
|
||||||
|
EXPECTATION_NULL,
|
||||||
|
INVALID_PARAMETER
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
public class FileUploadResponse extends BaseResponse {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
private String downloadUrl;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDownloadUrl() {
|
||||||
|
return downloadUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDownloadUrl(String downloadUrl) {
|
||||||
|
this.downloadUrl = downloadUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
public abstract class Screen {
|
||||||
|
public abstract void exec(Model model, HttpServletRequest request, HttpServletResponse response);
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SortTypeEnum - 排序方式
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public enum SortType {
|
||||||
|
|
||||||
|
//升序
|
||||||
|
ASC,
|
||||||
|
|
||||||
|
//降序
|
||||||
|
DESC
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
package xyz.wbsite.framework.base;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token - 通行证类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class Token implements Serializable {
|
||||||
|
private static final Long serialVersionUID = 1L;
|
||||||
|
/** ID */
|
||||||
|
private long id;
|
||||||
|
/** 用户ID */
|
||||||
|
private long userId;
|
||||||
|
/** 用户名称 */
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
private Set<String> resourceSet = new HashSet<>();
|
||||||
|
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(long userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName() {
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserName(String userName) {
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasResource(String resource){
|
||||||
|
for (String s : resourceSet) {
|
||||||
|
if (resource.matches(s)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putResource(String resource){
|
||||||
|
resourceSet.add(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getResourceSet() {
|
||||||
|
return resourceSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addResourceSet(Set<String> resourceSet){
|
||||||
|
this.resourceSet.addAll(resourceSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addResourceSet(Token token){
|
||||||
|
addResourceSet(token.getResourceSet());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
package xyz.wbsite.framework.config;
|
||||||
|
|
||||||
|
import xyz.wbsite.framework.base.Control;
|
||||||
|
import xyz.wbsite.framework.base.Screen;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||||
|
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||||
|
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReader;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
|
import org.springframework.core.type.filter.TypeFilter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class BeanDefinitionRegistryConfig implements BeanDefinitionRegistryPostProcessor {
|
||||||
|
public static final String SCREEN_PREFIX = "screen";
|
||||||
|
public static final String CONTROL_PREFIX = "control";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
|
||||||
|
String aPackage = this.getClass().getPackage().getName();
|
||||||
|
int i = registryScreen(aPackage.replaceAll("framework.config", "action.screen"), beanDefinitionRegistry);
|
||||||
|
int i1 = registryControl(aPackage.replaceAll("framework.config", "action.control"), beanDefinitionRegistry);
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private int registryScreen(String basePackage, BeanDefinitionRegistry beanDefinitionRegistry) {
|
||||||
|
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
|
||||||
|
classPathBeanDefinitionScanner.addIncludeFilter(new TypeFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
|
||||||
|
if (metadataReader.getClassMetadata().getSuperClassName().equals(Screen.class.getName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
classPathBeanDefinitionScanner.setBeanNameGenerator(new BeanNameGenerator() {
|
||||||
|
@Override
|
||||||
|
public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
|
||||||
|
String beanClassName = beanDefinition.getBeanClassName();
|
||||||
|
String s = beanClassName.replaceAll(basePackage, SCREEN_PREFIX);
|
||||||
|
return s.toLowerCase();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return classPathBeanDefinitionScanner.scan(basePackage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int registryControl(String basePackage, BeanDefinitionRegistry beanDefinitionRegistry) {
|
||||||
|
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
|
||||||
|
classPathBeanDefinitionScanner.addIncludeFilter(new TypeFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
|
||||||
|
if (metadataReader.getClassMetadata().getSuperClassName().equals(Control.class.getName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
classPathBeanDefinitionScanner.setBeanNameGenerator(new BeanNameGenerator() {
|
||||||
|
@Override
|
||||||
|
public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
|
||||||
|
String beanClassName = beanDefinition.getBeanClassName();
|
||||||
|
String s = beanClassName.replaceAll(basePackage, CONTROL_PREFIX);
|
||||||
|
return s.toLowerCase();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return classPathBeanDefinitionScanner.scan(basePackage);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
package xyz.wbsite.framework.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import xyz.wbsite.framework.base.Token;
|
||||||
|
import xyz.wbsite.framework.utils.CookieUtil;
|
||||||
|
import xyz.wbsite.framework.utils.LocalData;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableGlobalMethodSecurity(securedEnabled = true)
|
||||||
|
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Value("${web.url.auth.excluded}")
|
||||||
|
private String[] excluded;
|
||||||
|
@Value("${web.url.auth.included}")
|
||||||
|
private String[] included;
|
||||||
|
@Value("${web.url.login}")
|
||||||
|
private String login;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||||
|
.and()
|
||||||
|
.authorizeRequests()
|
||||||
|
.antMatchers(excluded).permitAll()
|
||||||
|
.antMatchers(included).access("@Authorization.hasPermission(request,authentication)")
|
||||||
|
.and().cors()
|
||||||
|
.and().headers().frameOptions().disable()
|
||||||
|
.and().csrf().disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 此方法不要删除 用于屏蔽默认用户密码生成
|
||||||
|
*
|
||||||
|
* 例如 Using generated security password: f6b42a66-71b1-4c31-b6a8-942838c81408
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||||
|
return super.authenticationManagerBean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean("Authorization")
|
||||||
|
public Object getAuthorization() {
|
||||||
|
return new Object() {
|
||||||
|
public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
|
||||||
|
|
||||||
|
// 获取Token
|
||||||
|
String token = request.getParameter("token");
|
||||||
|
if (token == null || token.isEmpty()){
|
||||||
|
token = CookieUtil.getCookieValue(request.getCookies(), "token");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token == null) {
|
||||||
|
LocalData.setToken(LocalData.getTempToken());
|
||||||
|
}else {
|
||||||
|
// 组装Token ~ 这边根据实际的业务组装Token
|
||||||
|
Token token1 = new Token();
|
||||||
|
token1.setId(1L);
|
||||||
|
token1.setUserId(1L);
|
||||||
|
token1.setUserName("admin");
|
||||||
|
//继承临时Token
|
||||||
|
token1.addResourceSet(LocalData.getTempToken());
|
||||||
|
//管理员特有资源
|
||||||
|
token1.putResource("/admin/.*");
|
||||||
|
LocalData.setToken(token1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 授权
|
||||||
|
Token token_ = LocalData.getToken();
|
||||||
|
if (token_.hasResource(request.getServletPath())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,105 @@
|
|||||||
|
package xyz.wbsite.framework.freemarker;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import xyz.wbsite.framework.config.BeanDefinitionRegistryConfig;
|
||||||
|
import freemarker.template.TemplateModelException;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.validation.support.BindingAwareModelMap;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
|
import org.springframework.web.servlet.LocaleResolver;
|
||||||
|
import org.springframework.web.servlet.View;
|
||||||
|
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.Locale;
|
||||||
|
import xyz.wbsite.framework.base.Control;
|
||||||
|
import xyz.wbsite.framework.utils.LocalData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 布局帮助类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class Layout {
|
||||||
|
|
||||||
|
@Value("${web.welcome.page}")
|
||||||
|
private String homePage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FreeMarkerViewResolver viewResolver;
|
||||||
|
|
||||||
|
private String screenPrefix = "/screen/";
|
||||||
|
private String controlPrefix = "/control/";
|
||||||
|
private String suffix = ".ftl";
|
||||||
|
|
||||||
|
public String setScreen() throws TemplateModelException {
|
||||||
|
try {
|
||||||
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||||
|
LocaleResolver localeResolver = (LocaleResolver) request.getAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE);
|
||||||
|
String servletPath = request.getServletPath();
|
||||||
|
if ("/".equals(servletPath)) {
|
||||||
|
servletPath = this.homePage;
|
||||||
|
}
|
||||||
|
if (servletPath.startsWith("/")) {
|
||||||
|
servletPath = servletPath.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去除头部/
|
||||||
|
String[] split = servletPath.split("/");
|
||||||
|
StringBuilder sb = new StringBuilder("");
|
||||||
|
|
||||||
|
// 分割组装路径
|
||||||
|
for (int i = 0; i < split.length; i++) {
|
||||||
|
sb.append(split[i]);
|
||||||
|
if (i != split.length - 1) {
|
||||||
|
sb.append(File.separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Locale locale = localeResolver.resolveLocale(request);
|
||||||
|
String viewName = "screen" + File.separator + sb.toString();
|
||||||
|
View view = viewResolver.resolveViewName(viewName, locale);
|
||||||
|
//无法找到对应screen
|
||||||
|
if (view == null) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return screenPrefix + servletPath + suffix;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String setControl(String control) {
|
||||||
|
|
||||||
|
// 查找是否存在对应控制面板执行器
|
||||||
|
Control controlExec = null;
|
||||||
|
try {
|
||||||
|
controlExec = LocalData.getApplicationContext().getBean(BeanDefinitionRegistryConfig.CONTROL_PREFIX + "." + control, Control.class);
|
||||||
|
|
||||||
|
HttpServletRequest request = LocalData.getRequest();
|
||||||
|
HttpServletResponse response = LocalData.getResponse();
|
||||||
|
|
||||||
|
BindingAwareModelMap modelMap = new BindingAwareModelMap();
|
||||||
|
controlExec.exec(modelMap, request, response);
|
||||||
|
|
||||||
|
for (String key : modelMap.keySet()) {
|
||||||
|
request.setAttribute(key, modelMap.get(key));
|
||||||
|
}
|
||||||
|
} catch (BeansException e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
control = control.replaceAll("/", File.separator);
|
||||||
|
return controlPrefix + control + suffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
package xyz.wbsite.framework.freemarker;
|
||||||
|
|
||||||
|
import freemarker.template.TemplateModelException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Url帮助类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class Uri {
|
||||||
|
|
||||||
|
public String getUrl(String path) throws TemplateModelException {
|
||||||
|
if (path == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path.startsWith("/")) {
|
||||||
|
return "/" + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||||
|
// 协议
|
||||||
|
String scheme = request.getScheme();
|
||||||
|
// 域名
|
||||||
|
String serverName = request.getServerName();
|
||||||
|
// 端口
|
||||||
|
int serverPort = request.getServerPort();
|
||||||
|
// 上下文路径
|
||||||
|
String contextPath = request.getContextPath();
|
||||||
|
|
||||||
|
return String.format(Locale.CHINA, "%s://%s:%d%s%s", scheme, serverName, serverPort, contextPath, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,122 @@
|
|||||||
|
package xyz.wbsite.framework.utils;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AESUtil 对称加密和解密工具类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class AESUtil {
|
||||||
|
|
||||||
|
private static final String ALGORITHM = "AES";
|
||||||
|
private static final String ALGORITHM_STR = "AES/ECB/PKCS5Padding";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密
|
||||||
|
*
|
||||||
|
* @param data 待加密字节数组
|
||||||
|
* @param secret 密钥
|
||||||
|
* @return base64字符串
|
||||||
|
*/
|
||||||
|
public static byte[] encrypt(byte[] data, String secret) {
|
||||||
|
try {
|
||||||
|
if (secret.length() != 16) {
|
||||||
|
throw new IllegalArgumentException("secret's length is not 16");
|
||||||
|
}
|
||||||
|
SecretKeySpec key = new SecretKeySpec(secret.getBytes(), ALGORITHM);
|
||||||
|
Cipher cipher = Cipher.getInstance(ALGORITHM_STR); // 创建密码器
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
|
||||||
|
return cipher.doFinal(data);// 加密
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密
|
||||||
|
*
|
||||||
|
* @param data 待加密字节数组
|
||||||
|
* @param secret 密钥
|
||||||
|
* @return base64字符串
|
||||||
|
*/
|
||||||
|
public static String encrypt2Base64(byte[] data, String secret) {
|
||||||
|
byte[] encrypt = encrypt(data, secret);
|
||||||
|
return Base64Util.encodeToString(encrypt, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解密
|
||||||
|
*
|
||||||
|
* @param data 待解密字节数组
|
||||||
|
* @param secret 密钥
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static byte[] decrypt(byte[] data, String secret) {
|
||||||
|
try {
|
||||||
|
if (secret.length() != 16) {
|
||||||
|
throw new IllegalArgumentException("secret's length is not 16");
|
||||||
|
}
|
||||||
|
SecretKeySpec key = new SecretKeySpec(secret.getBytes(), ALGORITHM);
|
||||||
|
Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, key);
|
||||||
|
return cipher.doFinal(data);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] decryptBase64(String base64Data, String secret) {
|
||||||
|
byte[] decode = Base64Util.decode(base64Data);
|
||||||
|
return decrypt(decode, secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decrypt2String(String base64Data, String secret) {
|
||||||
|
byte[] bytes = decryptBase64(base64Data, secret);
|
||||||
|
try {
|
||||||
|
return new String(bytes, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 加密
|
||||||
|
String data = "我有一个苹果";
|
||||||
|
String secret = "1234567890123456";
|
||||||
|
System.out.println("加密后的Base64密文是:" + AESUtil.encrypt2Base64(data.getBytes(), secret));
|
||||||
|
|
||||||
|
// 解密
|
||||||
|
String encrypt2Base64 = AESUtil.encrypt2Base64(data.getBytes(), secret);
|
||||||
|
byte[] decrypt = AESUtil.decrypt(Base64Util.decode(encrypt2Base64), secret);
|
||||||
|
System.out.println("解密后的明文是:" + new String(decrypt));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,506 @@
|
|||||||
|
package xyz.wbsite.framework.utils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64Util
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class Base64Util {
|
||||||
|
private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
|
||||||
|
private static final int[] IA = new int[256];
|
||||||
|
|
||||||
|
static {
|
||||||
|
Arrays.fill(IA, -1);
|
||||||
|
for (int i = 0, iS = CA.length; i < iS; i++)
|
||||||
|
IA[CA[i]] = i;
|
||||||
|
IA['='] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static String encodeToString(byte[] sArr) {
|
||||||
|
return new String(encodeToChar(sArr, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static char[] encodeToChar(byte[] sArr, boolean lineSep) {
|
||||||
|
// Check special case
|
||||||
|
int sLen = sArr != null ? sArr.length : 0;
|
||||||
|
if (sLen == 0)
|
||||||
|
return new char[0];
|
||||||
|
|
||||||
|
int eLen = (sLen / 3) * 3; // Length of even 24-bits.
|
||||||
|
int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
|
||||||
|
int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
|
||||||
|
char[] dArr = new char[dLen];
|
||||||
|
|
||||||
|
// Encode even 24-bits
|
||||||
|
for (int s = 0, d = 0, cc = 0; s < eLen; ) {
|
||||||
|
// Copy next three bytes into lower 24 bits of int, paying attension to sign.
|
||||||
|
int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
|
||||||
|
|
||||||
|
// Encode the int into four chars
|
||||||
|
dArr[d++] = CA[(i >>> 18) & 0x3f];
|
||||||
|
dArr[d++] = CA[(i >>> 12) & 0x3f];
|
||||||
|
dArr[d++] = CA[(i >>> 6) & 0x3f];
|
||||||
|
dArr[d++] = CA[i & 0x3f];
|
||||||
|
|
||||||
|
// Add optional line separator
|
||||||
|
if (lineSep && ++cc == 19 && d < dLen - 2) {
|
||||||
|
dArr[d++] = '\r';
|
||||||
|
dArr[d++] = '\n';
|
||||||
|
cc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pad and encode last bits if source isn't even 24 bits.
|
||||||
|
int left = sLen - eLen; // 0 - 2.
|
||||||
|
if (left > 0) {
|
||||||
|
// Prepare the int
|
||||||
|
int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
|
||||||
|
|
||||||
|
// Set last four chars
|
||||||
|
dArr[dLen - 4] = CA[i >> 12];
|
||||||
|
dArr[dLen - 3] = CA[(i >>> 6) & 0x3f];
|
||||||
|
dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '=';
|
||||||
|
dArr[dLen - 1] = '=';
|
||||||
|
}
|
||||||
|
return dArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes a raw byte array into a BASE64 <code>String</code> representation i accordance with RFC 2045.
|
||||||
|
*
|
||||||
|
* @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
|
||||||
|
* @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
|
||||||
|
* No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
|
||||||
|
* little faster.
|
||||||
|
* @return A BASE64 encoded array. Never <code>null</code>.
|
||||||
|
*/
|
||||||
|
public final static String encodeToString(byte[] sArr, boolean lineSep) {
|
||||||
|
// Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower.
|
||||||
|
return new String(encodeToChar(sArr, lineSep));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes a raw byte array into a BASE64 <code>byte[]</code> representation i accordance with RFC 2045.
|
||||||
|
*
|
||||||
|
* @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
|
||||||
|
* @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
|
||||||
|
* No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
|
||||||
|
* little faster.
|
||||||
|
* @return A BASE64 encoded array. Never <code>null</code>.
|
||||||
|
*/
|
||||||
|
public final static byte[] encodeToByte(byte[] sArr, boolean lineSep) {
|
||||||
|
// Check special case
|
||||||
|
int sLen = sArr != null ? sArr.length : 0;
|
||||||
|
if (sLen == 0)
|
||||||
|
return new byte[0];
|
||||||
|
|
||||||
|
int eLen = (sLen / 3) * 3; // Length of even 24-bits.
|
||||||
|
int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
|
||||||
|
int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
|
||||||
|
byte[] dArr = new byte[dLen];
|
||||||
|
|
||||||
|
// Encode even 24-bits
|
||||||
|
for (int s = 0, d = 0, cc = 0; s < eLen; ) {
|
||||||
|
// Copy next three bytes into lower 24 bits of int, paying attension to sign.
|
||||||
|
int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
|
||||||
|
|
||||||
|
// Encode the int into four chars
|
||||||
|
dArr[d++] = (byte) CA[(i >>> 18) & 0x3f];
|
||||||
|
dArr[d++] = (byte) CA[(i >>> 12) & 0x3f];
|
||||||
|
dArr[d++] = (byte) CA[(i >>> 6) & 0x3f];
|
||||||
|
dArr[d++] = (byte) CA[i & 0x3f];
|
||||||
|
|
||||||
|
// Add optional line separator
|
||||||
|
if (lineSep && ++cc == 19 && d < dLen - 2) {
|
||||||
|
dArr[d++] = '\r';
|
||||||
|
dArr[d++] = '\n';
|
||||||
|
cc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pad and encode last bits if source isn't an even 24 bits.
|
||||||
|
int left = sLen - eLen; // 0 - 2.
|
||||||
|
if (left > 0) {
|
||||||
|
// Prepare the int
|
||||||
|
int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
|
||||||
|
|
||||||
|
// Set last four chars
|
||||||
|
dArr[dLen - 4] = (byte) CA[i >> 12];
|
||||||
|
dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f];
|
||||||
|
dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '=';
|
||||||
|
dArr[dLen - 1] = '=';
|
||||||
|
}
|
||||||
|
return dArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static byte[] decode(char[] sArr) {
|
||||||
|
// Check special case
|
||||||
|
int sLen = sArr != null ? sArr.length : 0;
|
||||||
|
if (sLen == 0)
|
||||||
|
return new byte[0];
|
||||||
|
|
||||||
|
// Count illegal characters (including '\r', '\n') to know what size the returned array will be,
|
||||||
|
// so we don't have to reallocate & copy it later.
|
||||||
|
int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
|
||||||
|
for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
|
||||||
|
if (IA[sArr[i]] < 0)
|
||||||
|
sepCnt++;
|
||||||
|
|
||||||
|
// Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
|
||||||
|
if ((sLen - sepCnt) % 4 != 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
int pad = 0;
|
||||||
|
for (int i = sLen; i > 1 && IA[sArr[--i]] <= 0; )
|
||||||
|
if (sArr[i] == '=')
|
||||||
|
pad++;
|
||||||
|
|
||||||
|
int len = ((sLen - sepCnt) * 6 >> 3) - pad;
|
||||||
|
|
||||||
|
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
||||||
|
|
||||||
|
for (int s = 0, d = 0; d < len; ) {
|
||||||
|
// Assemble three bytes into an int from four "valid" characters.
|
||||||
|
int i = 0;
|
||||||
|
for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
|
||||||
|
int c = IA[sArr[s++]];
|
||||||
|
if (c >= 0)
|
||||||
|
i |= c << (18 - j * 6);
|
||||||
|
else
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
// Add the bytes
|
||||||
|
dArr[d++] = (byte) (i >> 16);
|
||||||
|
if (d < len) {
|
||||||
|
dArr[d++] = (byte) (i >> 8);
|
||||||
|
if (d < len)
|
||||||
|
dArr[d++] = (byte) i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes a BASE64 encoded byte array. All illegal characters will be ignored and can handle both arrays with
|
||||||
|
* and without line separators.
|
||||||
|
*
|
||||||
|
* @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
|
||||||
|
* @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
|
||||||
|
* (including '=') isn't divideable by 4. (I.e. definitely corrupted).
|
||||||
|
*/
|
||||||
|
public final static byte[] decode(byte[] sArr) {
|
||||||
|
// Check special case
|
||||||
|
int sLen = sArr.length;
|
||||||
|
|
||||||
|
// Count illegal characters (including '\r', '\n') to know what size the returned array will be,
|
||||||
|
// so we don't have to reallocate & copy it later.
|
||||||
|
int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
|
||||||
|
for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
|
||||||
|
if (IA[sArr[i] & 0xff] < 0)
|
||||||
|
sepCnt++;
|
||||||
|
|
||||||
|
// Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
|
||||||
|
if ((sLen - sepCnt) % 4 != 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
int pad = 0;
|
||||||
|
for (int i = sLen; i > 1 && IA[sArr[--i] & 0xff] <= 0; )
|
||||||
|
if (sArr[i] == '=')
|
||||||
|
pad++;
|
||||||
|
|
||||||
|
int len = ((sLen - sepCnt) * 6 >> 3) - pad;
|
||||||
|
|
||||||
|
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
||||||
|
|
||||||
|
for (int s = 0, d = 0; d < len; ) {
|
||||||
|
// Assemble three bytes into an int from four "valid" characters.
|
||||||
|
int i = 0;
|
||||||
|
for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
|
||||||
|
int c = IA[sArr[s++] & 0xff];
|
||||||
|
if (c >= 0)
|
||||||
|
i |= c << (18 - j * 6);
|
||||||
|
else
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the bytes
|
||||||
|
dArr[d++] = (byte) (i >> 16);
|
||||||
|
if (d < len) {
|
||||||
|
dArr[d++] = (byte) (i >> 8);
|
||||||
|
if (d < len)
|
||||||
|
dArr[d++] = (byte) i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes a BASE64 encoded byte array that is known to be resonably well formatted. The method is about twice as
|
||||||
|
* fast as {@link =#=decode(byte[])}. The preconditions are:<br>
|
||||||
|
* + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
|
||||||
|
* + Line separator must be "\r\n", as specified in RFC 2045
|
||||||
|
* + The array must not contain illegal characters within the encoded string<br>
|
||||||
|
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
|
||||||
|
*
|
||||||
|
* @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
|
||||||
|
* @return The decoded array of bytes. May be of length 0.
|
||||||
|
*/
|
||||||
|
public final static byte[] decodeFast(byte[] sArr) {
|
||||||
|
// Check special case
|
||||||
|
int sLen = sArr.length;
|
||||||
|
if (sLen == 0)
|
||||||
|
return new byte[0];
|
||||||
|
|
||||||
|
int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
|
||||||
|
|
||||||
|
// Trim illegal chars from start
|
||||||
|
while (sIx < eIx && IA[sArr[sIx] & 0xff] < 0)
|
||||||
|
sIx++;
|
||||||
|
|
||||||
|
// Trim illegal chars from end
|
||||||
|
while (eIx > 0 && IA[sArr[eIx] & 0xff] < 0)
|
||||||
|
eIx--;
|
||||||
|
|
||||||
|
// get the padding count (=) (0, 1 or 2)
|
||||||
|
int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end.
|
||||||
|
int cCnt = eIx - sIx + 1; // Content count including possible separators
|
||||||
|
int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
|
||||||
|
|
||||||
|
int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
|
||||||
|
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
||||||
|
|
||||||
|
// Decode all but the last 0 - 2 bytes.
|
||||||
|
int d = 0;
|
||||||
|
for (int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
|
||||||
|
// Assemble three bytes into an int from four "valid" characters.
|
||||||
|
int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
|
||||||
|
|
||||||
|
// Add the bytes
|
||||||
|
dArr[d++] = (byte) (i >> 16);
|
||||||
|
dArr[d++] = (byte) (i >> 8);
|
||||||
|
dArr[d++] = (byte) i;
|
||||||
|
|
||||||
|
// If line separator, jump over it.
|
||||||
|
if (sepCnt > 0 && ++cc == 19) {
|
||||||
|
sIx += 2;
|
||||||
|
cc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d < len) {
|
||||||
|
// Decode last 1-3 bytes (incl '=') into 1-3 bytes
|
||||||
|
int i = 0;
|
||||||
|
for (int j = 0; sIx <= eIx - pad; j++)
|
||||||
|
i |= IA[sArr[sIx++]] << (18 - j * 6);
|
||||||
|
|
||||||
|
for (int r = 16; d < len; r -= 8)
|
||||||
|
dArr[d++] = (byte) (i >> r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as
|
||||||
|
* fast as {@link =#=decode(char[])}. The preconditions are:<br>
|
||||||
|
* + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
|
||||||
|
* + Line separator must be "\r\n", as specified in RFC 2045
|
||||||
|
* + The array must not contain illegal characters within the encoded string<br>
|
||||||
|
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
|
||||||
|
*
|
||||||
|
* @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
|
||||||
|
* @return The decoded array of bytes. May be of length 0.
|
||||||
|
*/
|
||||||
|
public final static byte[] decodeFast(char[] sArr) {
|
||||||
|
// Check special case
|
||||||
|
int sLen = sArr.length;
|
||||||
|
if (sLen == 0)
|
||||||
|
return new byte[0];
|
||||||
|
|
||||||
|
int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
|
||||||
|
|
||||||
|
// Trim illegal chars from start
|
||||||
|
while (sIx < eIx && IA[sArr[sIx]] < 0)
|
||||||
|
sIx++;
|
||||||
|
|
||||||
|
// Trim illegal chars from end
|
||||||
|
while (eIx > 0 && IA[sArr[eIx]] < 0)
|
||||||
|
eIx--;
|
||||||
|
|
||||||
|
// get the padding count (=) (0, 1 or 2)
|
||||||
|
int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end.
|
||||||
|
int cCnt = eIx - sIx + 1; // Content count including possible separators
|
||||||
|
int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
|
||||||
|
|
||||||
|
int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
|
||||||
|
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
||||||
|
|
||||||
|
// Decode all but the last 0 - 2 bytes.
|
||||||
|
int d = 0;
|
||||||
|
for (int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
|
||||||
|
// Assemble three bytes into an int from four "valid" characters.
|
||||||
|
int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
|
||||||
|
|
||||||
|
// Add the bytes
|
||||||
|
dArr[d++] = (byte) (i >> 16);
|
||||||
|
dArr[d++] = (byte) (i >> 8);
|
||||||
|
dArr[d++] = (byte) i;
|
||||||
|
|
||||||
|
// If line separator, jump over it.
|
||||||
|
if (sepCnt > 0 && ++cc == 19) {
|
||||||
|
sIx += 2;
|
||||||
|
cc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d < len) {
|
||||||
|
// Decode last 1-3 bytes (incl '=') into 1-3 bytes
|
||||||
|
int i = 0;
|
||||||
|
for (int j = 0; sIx <= eIx - pad; j++)
|
||||||
|
i |= IA[sArr[sIx++]] << (18 - j * 6);
|
||||||
|
|
||||||
|
for (int r = 16; d < len; r -= 8)
|
||||||
|
dArr[d++] = (byte) (i >> r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes a BASE64 encoded <code>String</code>. All illegal characters will be ignored and can handle both strings with
|
||||||
|
* and without line separators.<br>
|
||||||
|
* <b>Note!</b> It can be up to about 2x the speed to call <code>decode(str.toCharArray())</code> instead. That
|
||||||
|
* will create a temporary array though. This version will use <code>str.charAt(i)</code> to iterate the string.
|
||||||
|
*
|
||||||
|
* @param str The source string. <code>null</code> or length 0 will return an empty array.
|
||||||
|
* @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
|
||||||
|
* (including '=') isn't divideable by 4. (I.e. definitely corrupted).
|
||||||
|
*/
|
||||||
|
public final static byte[] decode(String str) {
|
||||||
|
// Check special case
|
||||||
|
int sLen = str != null ? str.length() : 0;
|
||||||
|
if (sLen == 0)
|
||||||
|
return new byte[0];
|
||||||
|
|
||||||
|
// Count illegal characters (including '\r', '\n') to know what size the returned array will be,
|
||||||
|
// so we don't have to reallocate & copy it later.
|
||||||
|
int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
|
||||||
|
for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
|
||||||
|
if (IA[str.charAt(i)] < 0)
|
||||||
|
sepCnt++;
|
||||||
|
|
||||||
|
// Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
|
||||||
|
if ((sLen - sepCnt) % 4 != 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Count '=' at end
|
||||||
|
int pad = 0;
|
||||||
|
for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0; )
|
||||||
|
if (str.charAt(i) == '=')
|
||||||
|
pad++;
|
||||||
|
|
||||||
|
int len = ((sLen - sepCnt) * 6 >> 3) - pad;
|
||||||
|
|
||||||
|
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
||||||
|
|
||||||
|
for (int s = 0, d = 0; d < len; ) {
|
||||||
|
// Assemble three bytes into an int from four "valid" characters.
|
||||||
|
int i = 0;
|
||||||
|
for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
|
||||||
|
int c = IA[str.charAt(s++)];
|
||||||
|
if (c >= 0)
|
||||||
|
i |= c << (18 - j * 6);
|
||||||
|
else
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
// Add the bytes
|
||||||
|
dArr[d++] = (byte) (i >> 16);
|
||||||
|
if (d < len) {
|
||||||
|
dArr[d++] = (byte) (i >> 8);
|
||||||
|
if (d < len)
|
||||||
|
dArr[d++] = (byte) i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as
|
||||||
|
* fast as {@link =#=decode(String)}. The preconditions are:<br>
|
||||||
|
* + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
|
||||||
|
* + Line separator must be "\r\n", as specified in RFC 2045
|
||||||
|
* + The array must not contain illegal characters within the encoded string<br>
|
||||||
|
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
|
||||||
|
*
|
||||||
|
* @param str The source string. Length 0 will return an empty array. <code>null</code> will throw an exception.
|
||||||
|
* @return The decoded array of bytes. May be of length 0.
|
||||||
|
*/
|
||||||
|
public final static byte[] decodeFast(String str) {
|
||||||
|
// Check special case
|
||||||
|
int sLen = str.length();
|
||||||
|
if (sLen == 0)
|
||||||
|
return new byte[0];
|
||||||
|
|
||||||
|
int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
|
||||||
|
|
||||||
|
// Trim illegal chars from start
|
||||||
|
while (sIx < eIx && IA[str.charAt(sIx) & 0xff] < 0)
|
||||||
|
sIx++;
|
||||||
|
|
||||||
|
// Trim illegal chars from end
|
||||||
|
while (eIx > 0 && IA[str.charAt(eIx) & 0xff] < 0)
|
||||||
|
eIx--;
|
||||||
|
|
||||||
|
// get the padding count (=) (0, 1 or 2)
|
||||||
|
int pad = str.charAt(eIx) == '=' ? (str.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end.
|
||||||
|
int cCnt = eIx - sIx + 1; // Content count including possible separators
|
||||||
|
int sepCnt = sLen > 76 ? (str.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0;
|
||||||
|
|
||||||
|
int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
|
||||||
|
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
||||||
|
|
||||||
|
// Decode all but the last 0 - 2 bytes.
|
||||||
|
int d = 0;
|
||||||
|
for (int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
|
||||||
|
// Assemble three bytes into an int from four "valid" characters.
|
||||||
|
int i = IA[str.charAt(sIx++)] << 18 | IA[str.charAt(sIx++)] << 12 | IA[str.charAt(sIx++)] << 6 | IA[str.charAt(sIx++)];
|
||||||
|
|
||||||
|
// Add the bytes
|
||||||
|
dArr[d++] = (byte) (i >> 16);
|
||||||
|
dArr[d++] = (byte) (i >> 8);
|
||||||
|
dArr[d++] = (byte) i;
|
||||||
|
|
||||||
|
// If line separator, jump over it.
|
||||||
|
if (sepCnt > 0 && ++cc == 19) {
|
||||||
|
sIx += 2;
|
||||||
|
cc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d < len) {
|
||||||
|
// Decode last 1-3 bytes (incl '=') into 1-3 bytes
|
||||||
|
int i = 0;
|
||||||
|
for (int j = 0; sIx <= eIx - pad; j++)
|
||||||
|
i |= IA[str.charAt(sIx++)] << (18 - j * 6);
|
||||||
|
|
||||||
|
for (int r = 16; d < len; r -= 8)
|
||||||
|
dArr[d++] = (byte) (i >> r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String s = Base64Util.encodeToString(("我搜搜").getBytes());
|
||||||
|
System.out.println(s);
|
||||||
|
|
||||||
|
byte[] decode = Base64Util.decode(s);
|
||||||
|
System.out.println(new String(decode));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
package xyz.wbsite.framework.utils;
|
||||||
|
|
||||||
|
import xyz.wbsite.framework.base.Token;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LocalData - 本地数据存放类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class LocalData {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static Token temp = null;
|
||||||
|
|
||||||
|
private static Token system = null;
|
||||||
|
|
||||||
|
static {
|
||||||
|
temp = new Token();
|
||||||
|
temp.setId(-1);
|
||||||
|
temp.setUserId(-1);
|
||||||
|
temp.setUserName("游客");
|
||||||
|
temp.putResource("/ajax");
|
||||||
|
temp.putResource("/upload");
|
||||||
|
temp.putResource("ajax.example.example");
|
||||||
|
system = new Token();
|
||||||
|
system.setId(0);
|
||||||
|
system.setUserId(0);
|
||||||
|
system.setUserName("system");
|
||||||
|
system.putResource(".*");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Token getTempToken(){
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Token getSysToken() {
|
||||||
|
return system;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当请求目标 target = '/aa/bb'
|
||||||
|
*/
|
||||||
|
private static final ThreadLocal<String> targetHolder = new ThreadLocal();
|
||||||
|
|
||||||
|
public static String getTarget() {
|
||||||
|
return targetHolder.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setTarget(String target) {
|
||||||
|
targetHolder.set(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前用户的通行证
|
||||||
|
*/
|
||||||
|
private static final ThreadLocal<Token> tokenHolder = new ThreadLocal();
|
||||||
|
|
||||||
|
public static Token getToken() {
|
||||||
|
return tokenHolder.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setToken(Token token) {
|
||||||
|
tokenHolder.set(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HttpServletRequest getRequest() {
|
||||||
|
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HttpServletResponse getResponse() {
|
||||||
|
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ApplicationContext getApplicationContext() {
|
||||||
|
return WebApplicationContextUtils.getWebApplicationContext(getRequest().getServletContext());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
package xyz.wbsite.framework.utils;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.TreeNode;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MD5Util - MD5工具类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class MD5Util {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String encode(String value) {
|
||||||
|
try {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("md5");
|
||||||
|
byte[] e = md.digest(value.getBytes());
|
||||||
|
return toHexString(e);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encode(byte[] bytes) {
|
||||||
|
try {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("md5");
|
||||||
|
byte[] e = md.digest(bytes);
|
||||||
|
return toHexString(e);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toHexString(byte bytes[]) {
|
||||||
|
StringBuilder hs = new StringBuilder();
|
||||||
|
String stmp = "";
|
||||||
|
for (int n = 0; n < bytes.length; n++) {
|
||||||
|
stmp = Integer.toHexString(bytes[n] & 0xff);
|
||||||
|
if (stmp.length() == 1)
|
||||||
|
hs.append("0").append(stmp);
|
||||||
|
else
|
||||||
|
hs.append(stmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hs.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试实例
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// String encode = MD5Util.encode("123456");
|
||||||
|
// System.out.println(encode);
|
||||||
|
//
|
||||||
|
// UserCreateRequest user = new UserCreateRequest();
|
||||||
|
// user.setUser("wangbing");
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ArrayList<User> users = new ArrayList<>();
|
||||||
|
// User user1 = new User();
|
||||||
|
// user1.setUser("ddd");
|
||||||
|
// users.add(user1);
|
||||||
|
// user.setList(users);
|
||||||
|
//
|
||||||
|
// TreeNode treeNode = MapperUtil.toTree(user);
|
||||||
|
// String s = MapperUtil.toJson(user,true);
|
||||||
|
// System.out.println(s);
|
||||||
|
//
|
||||||
|
// String s1 = MD5Util.toSign(treeNode, "asasasdadasda", "wwwwwwwwwwwwwwww");
|
||||||
|
//
|
||||||
|
// System.out.println(s1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,133 @@
|
|||||||
|
package xyz.wbsite.framework.utils;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.core.TreeNode;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.*;
|
||||||
|
import org.dozer.DozerBeanMapper;
|
||||||
|
import org.dozer.Mapper;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MapUtil - 映射转化工具类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class MapperUtil {
|
||||||
|
private static ObjectMapper om;
|
||||||
|
private static Mapper mapper;
|
||||||
|
|
||||||
|
static {
|
||||||
|
//初始化
|
||||||
|
om = new ObjectMapper();
|
||||||
|
//序列化时忽略null属性
|
||||||
|
om.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||||
|
//序列化时排序
|
||||||
|
om.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
|
||||||
|
//反序列化是忽略多余字段
|
||||||
|
om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
//支持空类序列化时出错InvalidDefinitionException
|
||||||
|
om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
|
||||||
|
|
||||||
|
mapper = new DozerBeanMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TreeNode toTree(String json) {
|
||||||
|
try {
|
||||||
|
return om.readTree(json);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return om.createObjectNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TreeNode toTree(Object json) {
|
||||||
|
return om.valueToTree(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toJson(Object object) {
|
||||||
|
return toJson(object, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toJson(Object object, boolean pretty) {
|
||||||
|
try {
|
||||||
|
if (pretty) {
|
||||||
|
return om.writerWithDefaultPrettyPrinter().writeValueAsString(object);
|
||||||
|
} else {
|
||||||
|
return om.writeValueAsString(object);
|
||||||
|
}
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "{}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toJson(JsonNode jsonNode) {
|
||||||
|
return jsonNode.asText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T toJava(String json, Class<T> cls) {
|
||||||
|
try {
|
||||||
|
if (json == null || "".equals(json)) {
|
||||||
|
return cls.newInstance();
|
||||||
|
}
|
||||||
|
return om.readValue(json, cls);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T toJava(TreeNode treeNode, Class<T> cls) {
|
||||||
|
try {
|
||||||
|
return om.treeToValue(treeNode, cls);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T toJava(String json, TypeReference valueTypeRef) {
|
||||||
|
try {
|
||||||
|
return om.readValue(json, valueTypeRef);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> toJavaList(String json, TypeReference<List<T>> reference) {
|
||||||
|
try {
|
||||||
|
return om.readValue(json, reference);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> toJavaList(InputStream json, TypeReference<List<T>> reference) {
|
||||||
|
try {
|
||||||
|
return om.readValue(json, reference);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T map(Object o, Class<T> aClass) {
|
||||||
|
return mapper.map(o, aClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void map(Object o, Object o1) {
|
||||||
|
mapper.map(o, o1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package xyz.wbsite.framework.utils;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message - 基本消息类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class Message {
|
||||||
|
public static final String ERROR_500 = "服务器走了下神,稍后再试一次";
|
||||||
|
public static final String NOT_EXIST_METHOD = "调用的方法不存在";
|
||||||
|
|
||||||
|
public static String CREATE_FAILURE = "创建失败,请刷新后重新尝试";
|
||||||
|
public static String DELETE_FAILURE = "删除失败,请刷新后重新尝试";
|
||||||
|
public static String UPDATE_FAILURE = "更新失败,请刷新后重新尝试";
|
||||||
|
public static String FIND_FAILURE = "查询失败,请刷新后重新尝试";
|
||||||
|
public static String GET_FAILURE = "未获取相应内容";
|
||||||
|
public static String INSERT_DUPLICATE = "已经存在相同数据,返回列表页面确认";
|
||||||
|
}
|
||||||
@ -0,0 +1,330 @@
|
|||||||
|
package xyz.wbsite.framework.utils;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.security.*;
|
||||||
|
import java.security.interfaces.RSAPrivateKey;
|
||||||
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSAUtil - RSA工具类
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class RSAUtil {
|
||||||
|
|
||||||
|
private static String cryptPublicKeyBase64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTrwfsrJjCF+pP4S3A/wrD4U1txg53EuBC1mPt" +
|
||||||
|
"3vGXvSK2U0YNRVR3Q65ooHnPKmk4LwI8v+7+ATTxUg3qkuRiDuzBa5zLkYKM50LOgEWSdOKzbnbx" +
|
||||||
|
"a5FnE7IXawNt1p8+MVN1TTI7J/fZy6g1x0WBy1odE5Osru4WfZNOqQtjHwIDAQAB";
|
||||||
|
private static String cryptPrivateKeyBase64 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJOvB+ysmMIX6k/hLcD/CsPhTW3G" +
|
||||||
|
"DncS4ELWY+3e8Ze9IrZTRg1FVHdDrmigec8qaTgvAjy/7v4BNPFSDeqS5GIO7MFrnMuRgoznQs6A" +
|
||||||
|
"RZJ04rNudvFrkWcTshdrA23Wnz4xU3VNMjsn99nLqDXHRYHLWh0Tk6yu7hZ9k06pC2MfAgMBAAEC" +
|
||||||
|
"gYBjLRjKRMI1HfBZgmPChsPI9YWU4XuXVVLLL8Rd2uktOHOWM2gIw3VMvmPimVoT2GxesZr0BwTN" +
|
||||||
|
"CSxvnuX/kHPTqtsIu1r5Iup3mGbvlj3sn8RvG0yvUDglDN7QVDqqN7XWvHJSBVfBzDXeExA/WGnE" +
|
||||||
|
"6BOocNT9qkqA/UWNbCXGKQJBAN0Fd/P2D6EvCd2RztHhzVE6V8s/LwOTDnGn/YhdMpddy9TwZpBi" +
|
||||||
|
"r7I6lzcLWQ1HfDUive3t+DGXqPqr/4FfkG0CQQCrDlZKf216QrXOmJ70LQSbflgvGYU+b6kLFyEh" +
|
||||||
|
"+15HcIBfKUQCU+XUK4UzLMQDYxdngTNMNyq4AQ9Sh0tUTUI7AkEAtkq9XayzxWhLhcCtyTOoqPcq" +
|
||||||
|
"1Aqf1x3iCuHYXTEo+ek1pcJFhY6vhJuIfrDQWQB9tEGcTvI4A4cnquBTkzvjnQJAYid58ImqYmuB" +
|
||||||
|
"M6l0HJzwdeFL7MryIF+mWozNIFjDQq8VmoVtVwCZcuP+LN1VJLRpq6UBsIw/YRKKnkqwORGUHQJA" +
|
||||||
|
"UuR0G/3Hai+vKDA14tIYIH6C4zNmbULxAEuQVh9thfafWNmiDcifApvkxQ2ewXwEGeJtz44zv6iY" +
|
||||||
|
"3f3yq+a2OQ==";
|
||||||
|
|
||||||
|
private static String signPublicKeyBase64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTrwfsrJjCF+pP4S3A/wrD4U1txg53EuBC1mPt" +
|
||||||
|
"3vGXvSK2U0YNRVR3Q65ooHnPKmk4LwI8v+7+ATTxUg3qkuRiDuzBa5zLkYKM50LOgEWSdOKzbnbx" +
|
||||||
|
"a5FnE7IXawNt1p8+MVN1TTI7J/fZy6g1x0WBy1odE5Osru4WfZNOqQtjHwIDAQAB";
|
||||||
|
private static String signPrivateKeyBase64 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJOvB+ysmMIX6k/hLcD/CsPhTW3G" +
|
||||||
|
"DncS4ELWY+3e8Ze9IrZTRg1FVHdDrmigec8qaTgvAjy/7v4BNPFSDeqS5GIO7MFrnMuRgoznQs6A" +
|
||||||
|
"RZJ04rNudvFrkWcTshdrA23Wnz4xU3VNMjsn99nLqDXHRYHLWh0Tk6yu7hZ9k06pC2MfAgMBAAEC" +
|
||||||
|
"gYBjLRjKRMI1HfBZgmPChsPI9YWU4XuXVVLLL8Rd2uktOHOWM2gIw3VMvmPimVoT2GxesZr0BwTN" +
|
||||||
|
"CSxvnuX/kHPTqtsIu1r5Iup3mGbvlj3sn8RvG0yvUDglDN7QVDqqN7XWvHJSBVfBzDXeExA/WGnE" +
|
||||||
|
"6BOocNT9qkqA/UWNbCXGKQJBAN0Fd/P2D6EvCd2RztHhzVE6V8s/LwOTDnGn/YhdMpddy9TwZpBi" +
|
||||||
|
"r7I6lzcLWQ1HfDUive3t+DGXqPqr/4FfkG0CQQCrDlZKf216QrXOmJ70LQSbflgvGYU+b6kLFyEh" +
|
||||||
|
"+15HcIBfKUQCU+XUK4UzLMQDYxdngTNMNyq4AQ9Sh0tUTUI7AkEAtkq9XayzxWhLhcCtyTOoqPcq" +
|
||||||
|
"1Aqf1x3iCuHYXTEo+ek1pcJFhY6vhJuIfrDQWQB9tEGcTvI4A4cnquBTkzvjnQJAYid58ImqYmuB" +
|
||||||
|
"M6l0HJzwdeFL7MryIF+mWozNIFjDQq8VmoVtVwCZcuP+LN1VJLRpq6UBsIw/YRKKnkqwORGUHQJA" +
|
||||||
|
"UuR0G/3Hai+vKDA14tIYIH6C4zNmbULxAEuQVh9thfafWNmiDcifApvkxQ2ewXwEGeJtz44zv6iY" +
|
||||||
|
"3f3yq+a2OQ==";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建密钥和私钥
|
||||||
|
*/
|
||||||
|
public static void createKey() {
|
||||||
|
try {
|
||||||
|
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||||
|
keyPairGenerator.initialize(1024);
|
||||||
|
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||||
|
|
||||||
|
//公钥
|
||||||
|
RSAPublicKey aPublic = (RSAPublicKey) keyPair.getPublic();
|
||||||
|
//私钥
|
||||||
|
RSAPrivateKey aPrivate = (RSAPrivateKey) keyPair.getPrivate();
|
||||||
|
//把密钥对象对应的字节转为Base64字符存储
|
||||||
|
System.err.println("publicKeyBase64-->" + Base64Util.encodeToString(aPublic.getEncoded()));
|
||||||
|
System.err.println("privateKeyBase64-->" + Base64Util.encodeToString(aPrivate.getEncoded()));
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encrypt2Base64(byte[] data) {
|
||||||
|
byte[] encrypt = encrypt(data);
|
||||||
|
return Base64Util.encodeToString(encrypt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] encrypt(String data) {
|
||||||
|
return encrypt(data.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密
|
||||||
|
*
|
||||||
|
* @param data 待加密数据
|
||||||
|
*/
|
||||||
|
public static byte[] encrypt(byte[] data) {
|
||||||
|
try {
|
||||||
|
//生成公钥对象
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64Util.decode(cryptPublicKeyBase64));
|
||||||
|
PublicKey aPublic = keyFactory.generatePublic(x509EncodedKeySpec);
|
||||||
|
|
||||||
|
//分段加密开始
|
||||||
|
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||||
|
Cipher rsa = Cipher.getInstance("RSA");
|
||||||
|
rsa.init(Cipher.ENCRYPT_MODE, aPublic);
|
||||||
|
int offset = 0;
|
||||||
|
while (offset < data.length) {
|
||||||
|
byte[] bytes = rsa.doFinal(Arrays.copyOfRange(data, offset, Math.min(offset + 117, data.length)));
|
||||||
|
bs.write(bytes);
|
||||||
|
offset += 117;
|
||||||
|
}
|
||||||
|
return bs.toByteArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密
|
||||||
|
*
|
||||||
|
* @param data 待加密明文
|
||||||
|
*/
|
||||||
|
public static byte[] encrypt(String data, PublicKey aPublic) {
|
||||||
|
try {
|
||||||
|
if (aPublic == null) {
|
||||||
|
System.err.println("PublicKey can not be null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//分段加密开始
|
||||||
|
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||||
|
Cipher rsa = Cipher.getInstance("RSA");
|
||||||
|
rsa.init(Cipher.ENCRYPT_MODE, aPublic);
|
||||||
|
int offset = 0;
|
||||||
|
byte[] b = data.getBytes();
|
||||||
|
while (offset < b.length) {
|
||||||
|
byte[] bytes = rsa.doFinal(Arrays.copyOfRange(b, offset, Math.min(offset + 117, b.length)));
|
||||||
|
bs.write(bytes);
|
||||||
|
offset += 117;
|
||||||
|
}
|
||||||
|
return bs.toByteArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param base64String base64编码字符串
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static byte[] decrypt(String base64String) {
|
||||||
|
return decrypt(Base64Util.decode(base64String));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decrypt2String(String base64String) {
|
||||||
|
byte[] decrypt = decrypt(Base64Util.decode(base64String));
|
||||||
|
try {
|
||||||
|
return new String(decrypt, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解密
|
||||||
|
*
|
||||||
|
* @param data 已加密字节
|
||||||
|
*/
|
||||||
|
public static byte[] decrypt(byte[] data) {
|
||||||
|
try {
|
||||||
|
//生成私钥对象
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64Util.decode(cryptPrivateKeyBase64));
|
||||||
|
PrivateKey aPrivate = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
|
||||||
|
|
||||||
|
Cipher rsa = Cipher.getInstance("RSA");
|
||||||
|
rsa.init(Cipher.DECRYPT_MODE, aPrivate);
|
||||||
|
//获得密文字节
|
||||||
|
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||||
|
int offset = 0;
|
||||||
|
while (offset < data.length) {
|
||||||
|
byte[] bytes = rsa.doFinal(Arrays.copyOfRange(data, offset, Math.min(offset + 128, data.length)));
|
||||||
|
bs.write(bytes);
|
||||||
|
offset += 128;
|
||||||
|
}
|
||||||
|
return bs.toByteArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解密
|
||||||
|
*
|
||||||
|
* @param data 已加密字节
|
||||||
|
* @param aPrivate 公钥
|
||||||
|
* @return 解密后的字节
|
||||||
|
*/
|
||||||
|
public static byte[] decrypt(byte[] data, PublicKey aPrivate) {
|
||||||
|
try {
|
||||||
|
if (aPrivate == null) {
|
||||||
|
System.err.println("PublicKey can not be null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cipher rsa = Cipher.getInstance("RSA");
|
||||||
|
rsa.init(Cipher.DECRYPT_MODE, aPrivate);
|
||||||
|
//获得密文字节
|
||||||
|
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||||
|
int offset = 0;
|
||||||
|
while (offset < data.length) {
|
||||||
|
byte[] bytes = rsa.doFinal(Arrays.copyOfRange(data, offset, Math.min(offset + 128, data.length)));
|
||||||
|
bs.write(bytes);
|
||||||
|
offset += 128;
|
||||||
|
}
|
||||||
|
return bs.toByteArray();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String sign2Base64(byte[] data, String privateKey) {
|
||||||
|
byte[] sign = sign(data, privateKey);
|
||||||
|
return Base64Util.encodeToString(sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA签名
|
||||||
|
*
|
||||||
|
* @param data 待签名数据
|
||||||
|
* @param privateKey 私钥
|
||||||
|
* @return 签名字节数组
|
||||||
|
*/
|
||||||
|
public static byte[] sign(byte[] data, String privateKey) {
|
||||||
|
try {
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64Util.decode(privateKey));
|
||||||
|
PrivateKey aPrivate = keyFactory.generatePrivate(priPKCS8);
|
||||||
|
|
||||||
|
Signature signature = Signature.getInstance("SHA1WithRSA");
|
||||||
|
|
||||||
|
signature.initSign(aPrivate);
|
||||||
|
signature.update(data);
|
||||||
|
return signature.sign();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA验签名检查
|
||||||
|
*
|
||||||
|
* @param data 待签名数据
|
||||||
|
* @param sign base64 签名字符串
|
||||||
|
* @param publicKey 公钥
|
||||||
|
* @return 布尔值
|
||||||
|
*/
|
||||||
|
public static boolean doCheck(byte[] data, String sign, String publicKey) {
|
||||||
|
try {
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
byte[] encodedKey = Base64Util.decode(publicKey);
|
||||||
|
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
|
||||||
|
Signature signature = Signature.getInstance("SHA1WithRSA");
|
||||||
|
signature.initVerify(pubKey);
|
||||||
|
signature.update(data);
|
||||||
|
return signature.verify(Base64Util.decode(sign));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PublicKey parsePublicKey(String cryptPublicKeyBase64) {
|
||||||
|
try {
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64Util.decode(cryptPublicKeyBase64));
|
||||||
|
return keyFactory.generatePublic(x509EncodedKeySpec);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeySpecException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PrivateKey parsePrivateKey(String cryptPrivateKeyBase64) {
|
||||||
|
try {
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64Util.decode(cryptPrivateKeyBase64));
|
||||||
|
return keyFactory.generatePrivate(priPKCS8);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeySpecException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试实例
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
{//创建秘钥对
|
||||||
|
RSAUtil.createKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
{//加解密
|
||||||
|
|
||||||
|
//加密
|
||||||
|
String encrypt = RSAUtil.encrypt2Base64("我有一个苹果".getBytes());
|
||||||
|
System.out.println(encrypt);
|
||||||
|
|
||||||
|
//解密
|
||||||
|
String decrypt = RSAUtil.decrypt2String(encrypt);
|
||||||
|
System.out.println(decrypt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String sign = sign2Base64("我有一个苹果".getBytes(), signPrivateKeyBase64);
|
||||||
|
System.out.println(sign);
|
||||||
|
|
||||||
|
boolean b = doCheck("我有一个苹果".getBytes(), sign, signPublicKeyBase64);
|
||||||
|
System.out.println(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
package xyz.wbsite.framework.utils;
|
||||||
|
|
||||||
|
import xyz.wbsite.framework.base.BaseRequest;
|
||||||
|
import xyz.wbsite.framework.base.BaseResponse;
|
||||||
|
import xyz.wbsite.framework.base.ErrorType;
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
|
import javax.validation.Validation;
|
||||||
|
import javax.validation.Validator;
|
||||||
|
import javax.validation.ValidatorFactory;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证工具类。提供一些通用简单的数据验证功能
|
||||||
|
*
|
||||||
|
* @author wangbing
|
||||||
|
* @version 0.0.1
|
||||||
|
* @since 2017-01-01
|
||||||
|
*/
|
||||||
|
public class ValidationUtil {
|
||||||
|
|
||||||
|
private static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
||||||
|
|
||||||
|
public static <T extends BaseResponse> T validate(BaseRequest req, T response) {
|
||||||
|
|
||||||
|
if (req == null) {
|
||||||
|
response.addError(ErrorType.EXPECTATION_NULL, "请求对象不能为空");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Validator validator = factory.getValidator();
|
||||||
|
|
||||||
|
Set<ConstraintViolation<BaseRequest>> constraintViolations = validator.validate(req);
|
||||||
|
|
||||||
|
if (constraintViolations.size() > 0) {
|
||||||
|
for (ConstraintViolation<BaseRequest> violation : constraintViolations) {
|
||||||
|
response.addError(ErrorType.INVALID_PARAMETER, violation.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
LogUtil.dumpException(e);
|
||||||
|
response.addError(ErrorType.BUSINESS_ERROR, e.getMessage());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
# 开发环境
|
||||||
|
server.port=8080
|
||||||
|
server.servlet.context-path=/
|
||||||
|
spring.mvc.static-path-pattern=/static/**
|
||||||
|
spring.resources.static-locations=classpath:static/
|
||||||
|
spring.application.name=FILEMGR-WEB
|
||||||
|
# 编码配置
|
||||||
|
spring.http.encoding.force=true
|
||||||
|
spring.http.encoding.charset=UTF-8
|
||||||
|
spring.http.encoding.enabled=true
|
||||||
|
server.tomcat.uri-encoding=UTF-8
|
||||||
|
# 根路径、欢迎页
|
||||||
|
web.welcome.page = index
|
||||||
|
# 需要验证授权
|
||||||
|
web.url.auth.included = /**
|
||||||
|
# 不需要验证授权
|
||||||
|
web.url.auth.excluded = /static/**,/open/**,/api,/index,/,/login,/up
|
||||||
|
# 默认的登录URL
|
||||||
|
web.url.login = /login
|
||||||
|
# 日志配置
|
||||||
|
logging.path=D://
|
||||||
|
logging.levels=DEBUG
|
||||||
|
logging.config=classpath:logback-config.xml
|
||||||
|
# 热部署生效
|
||||||
|
spring.devtools.restart.enabled = true
|
||||||
|
# freemarker
|
||||||
|
spring.freemarker.enabled=true
|
||||||
|
spring.freemarker.allow-request-override=false
|
||||||
|
spring.freemarker.cache=true
|
||||||
|
spring.freemarker.check-template-location=true
|
||||||
|
spring.freemarker.charset=UTF-8
|
||||||
|
spring.freemarker.content-type=text/html
|
||||||
|
spring.freemarker.expose-request-attributes=false
|
||||||
|
spring.freemarker.expose-session-attributes=false
|
||||||
|
spring.freemarker.expose-spring-macro-helpers=false
|
||||||
|
spring.freemarker.settings.template_update_delay=1
|
||||||
|
spring.freemarker.settings.locale=zh_CN
|
||||||
|
spring.freemarker.settings.datetime_format=yyyy-MM-dd
|
||||||
|
spring.freemarker.settings.date_format=yyyy-MM-dd
|
||||||
|
spring.freemarker.settings.number_format=#.##
|
||||||
|
spring.freemarker.settings.classic_compatible=true
|
||||||
|
spring.freemarker.settings.whitespace_stripping=true
|
||||||
|
spring.freemarker.settings.url_escaping_charset=utf-8
|
||||||
|
# 文件上传配置
|
||||||
|
spring.servlet.multipart.resolveLazily = true
|
||||||
|
spring.servlet.multipart.max-file-size=100MB
|
||||||
|
spring.servlet.multipart.max-request-size=100MB
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
# 生产环境
|
||||||
|
server.port=80
|
||||||
|
server.servlet.context-path=/
|
||||||
|
spring.mvc.static-path-pattern=/static/**
|
||||||
|
spring.resources.static-locations=classpath:static/
|
||||||
|
spring.application.name=FILEMGR-WEB
|
||||||
|
spring.main.banner-mode=off
|
||||||
|
# 编码配置
|
||||||
|
spring.http.encoding.force=true
|
||||||
|
spring.http.encoding.charset=UTF-8
|
||||||
|
spring.http.encoding.enabled=true
|
||||||
|
server.tomcat.uri-encoding=UTF-8
|
||||||
|
# 根路径、欢迎页
|
||||||
|
web.welcome.page = index
|
||||||
|
# 需要验证授权
|
||||||
|
web.url.auth.included = /**
|
||||||
|
# 不需要验证授权
|
||||||
|
web.url.auth.excluded = /static/**,/open/**,/api,/index,/,/login
|
||||||
|
# 默认的登录URL
|
||||||
|
web.url.login = /login
|
||||||
|
# 日志配置
|
||||||
|
logging.path = /root/
|
||||||
|
logging.levels=INFO
|
||||||
|
logging.config = classpath:logback-config.xml
|
||||||
|
# freemarker
|
||||||
|
spring.freemarker.enabled=true
|
||||||
|
spring.freemarker.allow-request-override=false
|
||||||
|
spring.freemarker.cache=true
|
||||||
|
spring.freemarker.check-template-location=true
|
||||||
|
spring.freemarker.charset=UTF-8
|
||||||
|
spring.freemarker.content-type=text/html
|
||||||
|
spring.freemarker.expose-request-attributes=false
|
||||||
|
spring.freemarker.expose-session-attributes=false
|
||||||
|
spring.freemarker.expose-spring-macro-helpers=false
|
||||||
|
spring.freemarker.settings.template_update_delay=1
|
||||||
|
spring.freemarker.settings.locale=zh_CN
|
||||||
|
spring.freemarker.settings.datetime_format=yyyy-MM-dd
|
||||||
|
spring.freemarker.settings.date_format=yyyy-MM-dd
|
||||||
|
spring.freemarker.settings.number_format=#.##
|
||||||
|
spring.freemarker.settings.classic_compatible=true
|
||||||
|
spring.freemarker.settings.whitespace_stripping=true
|
||||||
|
spring.freemarker.settings.url_escaping_charset=utf-8
|
||||||
|
# 文件上传配置
|
||||||
|
spring.servlet.multipart.resolveLazily = true
|
||||||
|
spring.servlet.multipart.max-file-size=100MB
|
||||||
|
spring.servlet.multipart.max-request-size=100MB
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
${AnsiColor.BRIGHT_YELLOW}
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
// _ooOoo_ //
|
||||||
|
// o8888888o //
|
||||||
|
// 88" . "88 //
|
||||||
|
// (| ^_^ |) //
|
||||||
|
// O\ = /O //
|
||||||
|
// ____/`---'\____ //
|
||||||
|
// .' \\| |// `. //
|
||||||
|
// / \\||| : |||// \ //
|
||||||
|
// / _||||| -:- |||||- \ //
|
||||||
|
// | | \\\ - /// | | //
|
||||||
|
// | \_| ''\---/'' | | //
|
||||||
|
// \ .-\__ `-` ___/-. / //
|
||||||
|
// ___`. .' /--.--\ `. . ___ //
|
||||||
|
// ."" '< `.___\_<|>_/___.' >'"". //
|
||||||
|
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
|
||||||
|
// \ \ `-. \_ __\ /__ _/ .-` / / //
|
||||||
|
// ========`-.____`-.___\_____/___.-`____.-'======== //
|
||||||
|
// `=---=' //
|
||||||
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
佛祖保佑 永无BUG
|
||||||
|
_ _ _
|
||||||
|
| | | | (_)
|
||||||
|
| |__ _ _ __ __ __ _ _ __ __ _ | |__ _ _ __ __ _
|
||||||
|
| '_ \ | | | | \ \ /\ / / / _` || '_ \ / _` | | '_ \ | || '_ \ / _` |
|
||||||
|
| |_) || |_| | \ V V / | (_| || | | || (_| | | |_) || || | | || (_| |
|
||||||
|
|_.__/ \__, | \_/\_/ \__,_||_| |_| \__, | |_.__/ |_||_| |_| \__, |
|
||||||
|
__/ | __/ | __/ |
|
||||||
|
|___/ |___/ |___/
|
||||||
|
|
||||||
|
:: Spring Boot :: ${spring-boot.formatted-version} (${spring.profiles.active})
|
||||||
|
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<project>
|
||||||
|
<projectName>FILEMGR-WEB</projectName>
|
||||||
|
<projectBasePackage>xyz.wbsite</projectBasePackage>
|
||||||
|
<projectAuthor>wangbing</projectAuthor>
|
||||||
|
<modules>
|
||||||
|
<module>
|
||||||
|
<moduleComment>文件管理</moduleComment>
|
||||||
|
<modulePrefix>FM_</modulePrefix>
|
||||||
|
<moduleName>filemgr</moduleName>
|
||||||
|
<hasSysFields>true</hasSysFields>
|
||||||
|
<tables>
|
||||||
|
<table create="true" delete="true" find="true" get="true" getAll="false" search="false" tableComment="注释" tableName="NEW_TABLE" update="true">
|
||||||
|
<fields>
|
||||||
|
<field IsSystem="true" defaultValue="" fieldComment="主键" fieldLength="0" fieldName="ID" fieldType="Long" isMust="true" isPrimaryKey="true" isQuery="false" isSearch="false"/>
|
||||||
|
<field IsSystem="true" defaultValue="" fieldComment="行版本" fieldLength="0" fieldName="ROW_VERSION" fieldType="Long" isMust="true" isPrimaryKey="false" isQuery="false" isSearch="false"/>
|
||||||
|
<field IsSystem="true" defaultValue="0" fieldComment="是否已删除" fieldLength="0" fieldName="IS_DELETED" fieldType="Boolean" isMust="true" isPrimaryKey="false" isQuery="false" isSearch="false"/>
|
||||||
|
<field IsSystem="true" defaultValue="" fieldComment="创建用户" fieldLength="0" fieldName="CREATE_BY" fieldType="Long" isMust="true" isPrimaryKey="false" isQuery="false" isSearch="false"/>
|
||||||
|
<field IsSystem="true" defaultValue="NULL" fieldComment="创建时间" fieldLength="0" fieldName="CREATE_TIME" fieldType="Date" isMust="true" isPrimaryKey="false" isQuery="false" isSearch="false"/>
|
||||||
|
<field IsSystem="true" defaultValue="" fieldComment="最后更新用户" fieldLength="0" fieldName="LAST_UPDATE_BY" fieldType="Long" isMust="false" isPrimaryKey="false" isQuery="false" isSearch="false"/>
|
||||||
|
<field IsSystem="true" defaultValue="" fieldComment="最后更新时间" fieldLength="0" fieldName="LAST_UPDATE_TIME" fieldType="Date" isMust="false" isPrimaryKey="false" isQuery="false" isSearch="false"/>
|
||||||
|
</fields>
|
||||||
|
</table>
|
||||||
|
</tables>
|
||||||
|
</module>
|
||||||
|
</modules>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for NEW_TABLE - 注释
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TABLE `FM_NEW_TABLE` (
|
||||||
|
`ID` BIGINT(20) NOT NULL COMMENT '主键',
|
||||||
|
`ROW_VERSION` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '行版本',
|
||||||
|
`IS_DELETED` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已删除',
|
||||||
|
`CREATE_BY` BIGINT(20) NOT NULL COMMENT '创建用户',
|
||||||
|
`CREATE_TIME` DATETIME NOT NULL COMMENT '创建时间',
|
||||||
|
`LAST_UPDATE_BY` BIGINT(20) DEFAULT NULL COMMENT '最后更新用户',
|
||||||
|
`LAST_UPDATE_TIME` DATETIME DEFAULT NULL COMMENT '最后更新时间',
|
||||||
|
PRIMARY KEY (`ID`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='注释';
|
||||||
|
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
Target : MYSQL
|
||||||
|
Author
|
||||||
|
Date: 2019-02-15
|
||||||
|
*/
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for NEW_TABLE - 注释
|
||||||
|
-- ----------------------------
|
||||||
|
|
||||||
|
CREATE TABLE `FM_NEW_TABLE` (
|
||||||
|
`ID` BIGINT(20) NOT NULL COMMENT '主键',
|
||||||
|
`ROW_VERSION` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '行版本',
|
||||||
|
`IS_DELETED` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已删除',
|
||||||
|
`CREATE_BY` BIGINT(20) NOT NULL COMMENT '创建用户',
|
||||||
|
`CREATE_TIME` DATETIME NOT NULL COMMENT '创建时间',
|
||||||
|
`LAST_UPDATE_BY` BIGINT(20) DEFAULT NULL COMMENT '最后更新用户',
|
||||||
|
`LAST_UPDATE_TIME` DATETIME DEFAULT NULL COMMENT '最后更新时间',
|
||||||
|
PRIMARY KEY (`ID`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='注释';
|
||||||
Binary file not shown.
@ -0,0 +1,109 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||||
|
|
||||||
|
<!-- 日志根目录 -->
|
||||||
|
<springProperty scope="context" name="root" source="logging.path"/>
|
||||||
|
<!-- 日志等级 -->
|
||||||
|
<springProperty scope="context" name="level" source="logging.level"/>
|
||||||
|
|
||||||
|
<!-- 迭代日志All级别文件 -->
|
||||||
|
<appender name="RollingFile_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<File>${root}log/all/all.log</File>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<FileNamePattern>${root}log/all/all-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
|
||||||
|
<MaxHistory>30</MaxHistory>
|
||||||
|
<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||||
|
<MaxFileSize>10MB</MaxFileSize>
|
||||||
|
</TimeBasedFileNamingAndTriggeringPolicy>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>[%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
|
<level>INFO</level>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 迭代日志error级别文件 -->
|
||||||
|
<appender name="RollingFile_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<File>${root}log/error/error.log</File>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<FileNamePattern>${root}log/error/error-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
|
||||||
|
<MaxHistory>30</MaxHistory>
|
||||||
|
<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||||
|
<MaxFileSize>10MB</MaxFileSize>
|
||||||
|
</TimeBasedFileNamingAndTriggeringPolicy>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>[%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<level>ERROR</level>
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 迭代日志warn级别文件 -->
|
||||||
|
<appender name="RollingFile_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<File>${root}log/warn/warn.log</File>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<FileNamePattern>${root}log/warn/warn-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
|
||||||
|
<MaxHistory>30</MaxHistory>
|
||||||
|
<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||||
|
<MaxFileSize>10MB</MaxFileSize>
|
||||||
|
</TimeBasedFileNamingAndTriggeringPolicy>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>[%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<level>WARN</level>
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 迭代日志info级别文件 -->
|
||||||
|
<appender name="RollingFile_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<File>${root}log/info/info.log</File>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<FileNamePattern>${root}log/info/info-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
|
||||||
|
<MaxHistory>30</MaxHistory>
|
||||||
|
<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||||
|
<MaxFileSize>10MB</MaxFileSize>
|
||||||
|
</TimeBasedFileNamingAndTriggeringPolicy>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>[%-4level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%logger{36}-%method] %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<level>INFO</level>
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
debug级别及以上
|
||||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
|
<level>DEBUG</level>
|
||||||
|
</filter>
|
||||||
|
<encoder>
|
||||||
|
<pattern>%highlight(%d{yyyy-MM-dd HH:mm:ss.SSS} [%-4level] [%thread] [%logger{36}-%method] %ex %msg%n)</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<logger name="java.sql" level="INFO"></logger>
|
||||||
|
|
||||||
|
<!-- 日志总入口 -->
|
||||||
|
<root level="${level}">
|
||||||
|
<appender-ref ref="RollingFile_ALL"/>
|
||||||
|
<appender-ref ref="RollingFile_ERROR"/>
|
||||||
|
<appender-ref ref="RollingFile_WARN"/>
|
||||||
|
<appender-ref ref="RollingFile_INFO"/>
|
||||||
|
<appender-ref ref="Console"/>
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
@echo off
|
||||||
|
cd %cd%
|
||||||
|
start java -Dfile.encoding=UTF-8 -jar FILEMGR-WEB-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
@echo off
|
||||||
|
cd %cd%
|
||||||
|
start java -Dfile.encoding=UTF-8 -jar FILEMGR-WEB-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
|
||||||
@ -0,0 +1,786 @@
|
|||||||
|
* {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
line-height: 1.15;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #515a6e;
|
||||||
|
background-color: #fff;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
article, aside, footer, header, nav, section {
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
margin: .67em 0
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption, figure, main {
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 1em 40px
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
-webkit-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
height: 0;
|
||||||
|
overflow: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
font-family: monospace, monospace;
|
||||||
|
font-size: 1em
|
||||||
|
}
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
border-bottom: none;
|
||||||
|
text-decoration: underline;
|
||||||
|
-webkit-text-decoration: underline dotted;
|
||||||
|
text-decoration: underline dotted
|
||||||
|
}
|
||||||
|
|
||||||
|
b, strong {
|
||||||
|
font-weight: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
b, strong {
|
||||||
|
font-weight: bolder
|
||||||
|
}
|
||||||
|
|
||||||
|
code, kbd, samp {
|
||||||
|
font-family: monospace, monospace;
|
||||||
|
font-size: 1em
|
||||||
|
}
|
||||||
|
|
||||||
|
dfn {
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
background-color: #ff0;
|
||||||
|
color: #000
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 80%
|
||||||
|
}
|
||||||
|
|
||||||
|
sub, sup {
|
||||||
|
font-size: 75%;
|
||||||
|
line-height: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: baseline
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -.25em
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -.5em
|
||||||
|
}
|
||||||
|
|
||||||
|
audio, video {
|
||||||
|
display: inline-block
|
||||||
|
}
|
||||||
|
|
||||||
|
audio:not([controls]) {
|
||||||
|
display: none;
|
||||||
|
height: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-style: none
|
||||||
|
}
|
||||||
|
|
||||||
|
svg:not(:root) {
|
||||||
|
overflow: hidden
|
||||||
|
}
|
||||||
|
|
||||||
|
button, input, optgroup, select, textarea {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 100%;
|
||||||
|
line-height: 1.15;
|
||||||
|
margin: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
button, input {
|
||||||
|
overflow: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
button, select {
|
||||||
|
text-transform: none
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=reset], [type=submit], button, html [type=button] {
|
||||||
|
-webkit-appearance: button
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=button]::-moz-focus-inner, [type=reset]::-moz-focus-inner, [type=submit]::-moz-focus-inner, button::-moz-focus-inner {
|
||||||
|
border-style: none;
|
||||||
|
padding: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=button]:-moz-focusring, [type=reset]:-moz-focusring, [type=submit]:-moz-focusring, button:-moz-focusring {
|
||||||
|
outline: 1px dotted ButtonText
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
border: 1px solid silver;
|
||||||
|
margin: 0 2px;
|
||||||
|
padding: .35em .625em .75em
|
||||||
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: inherit;
|
||||||
|
display: table;
|
||||||
|
max-width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
white-space: normal
|
||||||
|
}
|
||||||
|
|
||||||
|
progress {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: baseline
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
overflow: auto;
|
||||||
|
resize: vertical
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=checkbox], [type=radio] {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=number]::-webkit-inner-spin-button, [type=number]::-webkit-outer-spin-button {
|
||||||
|
height: auto
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=search] {
|
||||||
|
-webkit-appearance: textfield;
|
||||||
|
outline-offset: -2px
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=search]::-webkit-search-cancel-button, [type=search]::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-file-upload-button {
|
||||||
|
-webkit-appearance: button;
|
||||||
|
font: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
details, menu {
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: list-item
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
display: inline-block
|
||||||
|
}
|
||||||
|
|
||||||
|
template {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
:after, :before {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box
|
||||||
|
}
|
||||||
|
|
||||||
|
article, aside, blockquote, body, button, dd, details, div, dl, dt, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, input, legend, li, menu, nav, ol, p, section, td, textarea, th, ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
button, input, select, textarea {
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
input::-ms-clear, input::-ms-reveal {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
outline: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-transition: color .2s ease;
|
||||||
|
transition: color .2s ease;
|
||||||
|
-webkit-text-decoration-skip: objects;
|
||||||
|
color: #757575;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:active, a:hover {
|
||||||
|
outline-width: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:active {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:active, a:hover {
|
||||||
|
outline: 0;
|
||||||
|
text-decoration: none
|
||||||
|
}
|
||||||
|
|
||||||
|
a[disabled] {
|
||||||
|
color: #ccc;
|
||||||
|
cursor: not-allowed;
|
||||||
|
pointer-events: none
|
||||||
|
}
|
||||||
|
|
||||||
|
code, kbd, pre, samp {
|
||||||
|
font-family: Consolas, Menlo, Courier, monospace
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*主标题*/
|
||||||
|
h1 {
|
||||||
|
font-size: 20px;
|
||||||
|
padding: 10px 0px;
|
||||||
|
margin: 20px 0px 10px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*标题*/
|
||||||
|
h2 {
|
||||||
|
font-size: 18px;
|
||||||
|
padding: 9px 0px;
|
||||||
|
margin: 18px 0px 8px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*小标题*/
|
||||||
|
h3 {
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 8px 0px;
|
||||||
|
margin: 16px 0px 6px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*次要标题*/
|
||||||
|
h4 {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 4px 0px;
|
||||||
|
margin: 4px 0px 4px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 7px 0px;
|
||||||
|
color: #545C64;;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.text-indent {
|
||||||
|
text-indent: 2em
|
||||||
|
}
|
||||||
|
|
||||||
|
/*正文*/
|
||||||
|
.text-regular {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*正文(小)*/
|
||||||
|
.text-small {
|
||||||
|
font-size: 13px
|
||||||
|
}
|
||||||
|
|
||||||
|
/*辅助文字*/
|
||||||
|
.text-smaller {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
/*中文字体*/
|
||||||
|
.typo-PingFang {
|
||||||
|
font-family: PingFang SC
|
||||||
|
}
|
||||||
|
|
||||||
|
.typo-Hiragino {
|
||||||
|
font-family: Hiragino Sans GB
|
||||||
|
}
|
||||||
|
|
||||||
|
.typo-Microsoft {
|
||||||
|
font-family: Microsoft YaHei
|
||||||
|
}
|
||||||
|
|
||||||
|
/*英文/数字字体*/
|
||||||
|
.typo-Helvetica-Neue {
|
||||||
|
font-family: Helvetica Neue
|
||||||
|
}
|
||||||
|
|
||||||
|
.typo-Helvetica {
|
||||||
|
font-family: Helvetica
|
||||||
|
}
|
||||||
|
|
||||||
|
.typo-Arial {
|
||||||
|
font-family: Arial
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-blue {
|
||||||
|
background-color: #409eff
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-success {
|
||||||
|
background-color: #67c23a
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-warning {
|
||||||
|
background-color: #e6a23c
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-danger {
|
||||||
|
background-color: #f56c6c
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-info {
|
||||||
|
background-color: #909399
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-color-primary {
|
||||||
|
color: #303133
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-color-regular {
|
||||||
|
color: #606266
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-color-secondary {
|
||||||
|
color: #909399
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-color-placeholder {
|
||||||
|
color: #c0c4cc
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-border-base {
|
||||||
|
background-color: #dcdfe6
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-border-light {
|
||||||
|
background-color: #e4e7ed
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-border-lighter {
|
||||||
|
background-color: #ebeef5
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-border-extra-light {
|
||||||
|
background-color: #f2f6fc
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="bg-border-"] {
|
||||||
|
color: #303133
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: #f9fafc;
|
||||||
|
padding: 0 4px;
|
||||||
|
border: 1px solid #eaeefb;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remarks {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399
|
||||||
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell {
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell.center {
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell.v-center {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell.h-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell.right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell.left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell.top {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell.bottom {
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-10 {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-20 {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-30 {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-40 {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-t-50 {
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
.center{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.full {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nowrap {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
word-break: keep-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
[v-cloak] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 可以设置不同的进入和离开动画 */
|
||||||
|
/* 设置持续时间和动画函数 */
|
||||||
|
.left-in-right-out-enter-active, .left-in-right-out-leave-active {
|
||||||
|
transition: all 0.3s linear;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-in-right-out-enter
|
||||||
|
/* .slide-fade-leave-active for below version 2.1.8 */
|
||||||
|
{
|
||||||
|
transform: translateX(-100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-in-right-out-leave-to
|
||||||
|
/* .slide-fade-leave-active for below version 2.1.8 */
|
||||||
|
{
|
||||||
|
transform: translateX(100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-in-left-out-enter-active, .right-in-left-out-leave-active {
|
||||||
|
transition: all .3s linear;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-in-left-out-enter {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-in-left-out-leave-to {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-switch__input:focus ~ .el-switch__core {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
outline: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=col-] {
|
||||||
|
float: left;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1 {
|
||||||
|
width: 4.16667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-2 {
|
||||||
|
width: 8.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-3 {
|
||||||
|
width: 12.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-4 {
|
||||||
|
width: 16.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-5 {
|
||||||
|
width: 20.83333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-6 {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-7 {
|
||||||
|
width: 29.16667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-8 {
|
||||||
|
width: 33.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-9 {
|
||||||
|
width: 37.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-10 {
|
||||||
|
width: 41.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-11 {
|
||||||
|
width: 45.83333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-12 {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-13 {
|
||||||
|
width: 54.16667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-14 {
|
||||||
|
width: 58.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-15 {
|
||||||
|
width: 62.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-16 {
|
||||||
|
width: 66.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-17 {
|
||||||
|
width: 70.83333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-18 {
|
||||||
|
width: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-19 {
|
||||||
|
width: 79.16667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-20 {
|
||||||
|
width: 83.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-21 {
|
||||||
|
width: 87.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-22 {
|
||||||
|
width: 91.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-23 {
|
||||||
|
width: 95.83333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-24 {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page_list {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page_list a {
|
||||||
|
display: inline-block;
|
||||||
|
height: 35px;
|
||||||
|
width: 35px;
|
||||||
|
line-height: 35px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page_list a.disabled {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page_list a.current {
|
||||||
|
background-color: #16C0F8;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page_list a:hover {
|
||||||
|
background-color: #16C0F8;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page_list a.disabled:hover {
|
||||||
|
background-color: #373737;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page_list a.top_page,
|
||||||
|
.page_list a.page_prev,
|
||||||
|
.page_list a.page_next,
|
||||||
|
.page_list a.end_page {
|
||||||
|
width: 55px;
|
||||||
|
padding: 0px 5px;
|
||||||
|
}
|
||||||
|
.page_list p{
|
||||||
|
padding: 0px 20px;
|
||||||
|
line-height: 35px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #16C0F8;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-scrollbar.hidden_x > .el-scrollbar__wrap {
|
||||||
|
overflow-x: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-scrollbar.hidden_x > .el-scrollbar__wrap > .el-scrollbar__view {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-menu--horizontal {
|
||||||
|
border-bottom: solid 0px #e6e6e6 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-message {
|
||||||
|
min-width: 100px;
|
||||||
|
padding: 10px 60px 10px 20px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
box-shadow: 0 1px 6px rgba(0, 0, 0, .2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-bar {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0px;
|
||||||
|
top: 0px;
|
||||||
|
box-shadow: 0px 0px 0px 0px;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-bar .el-message__content {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-bar .el-message__content .bar {
|
||||||
|
display: block;
|
||||||
|
height: 2px;
|
||||||
|
background-color: #2d8cf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-bar .el-message__content .bar.error {
|
||||||
|
background-color: #ff1a0e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 带有固定title布局,title保持固定*/
|
||||||
|
.wb-layout-title-fix {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wb-layout-title-fix > .wb-head {
|
||||||
|
height: 60px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wb-layout-title-fix > .wb-body {
|
||||||
|
height: calc(100% - 60px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 保持页脚绝对底部,当内容足够或高于屏幕,会自动将页面撑开,底部依旧保持在底部*/
|
||||||
|
.wb-layout-foot-absolute {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wb-layout-foot-absolute > .wb-body {
|
||||||
|
padding-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wb-layout-foot-absolute > .wb-foot {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0px;
|
||||||
|
height: 50px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 264 B |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,135 @@
|
|||||||
|
//创建axios实例
|
||||||
|
instance = axios.create({
|
||||||
|
method: 'post',
|
||||||
|
timeout: 30000,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加请求拦截器
|
||||||
|
instance.interceptors.request.use(function (config) {
|
||||||
|
// 在发送请求之前做些什么
|
||||||
|
nav.bar.show();
|
||||||
|
if (config.url == '/upload') {
|
||||||
|
nav.tip.show("上传中 ...");
|
||||||
|
} else {
|
||||||
|
nav.tip.show();
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}, function (error) {
|
||||||
|
// 对请求错误做些什么
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加响应拦截器
|
||||||
|
instance.interceptors.response.use(function (response) {
|
||||||
|
// 对响应数据做点什么
|
||||||
|
nav.tip.close();
|
||||||
|
nav.bar.finish();
|
||||||
|
return response;
|
||||||
|
}, function (error) {
|
||||||
|
// 对响应错误做点什么
|
||||||
|
nav.tip.close();
|
||||||
|
nav.bar.error();
|
||||||
|
const rsp = {errors: []};
|
||||||
|
if (!error.response) {
|
||||||
|
rsp.errors.push({message: error.message});
|
||||||
|
} else {
|
||||||
|
switch (error.response.status) {
|
||||||
|
case 401:
|
||||||
|
rsp.errors.push({message: "未授权,请登录(401)"});
|
||||||
|
break
|
||||||
|
case 403:
|
||||||
|
rsp.errors.push({message: "拒绝访问(403)"});
|
||||||
|
break
|
||||||
|
case 404:
|
||||||
|
rsp.errors.push({message: "请求地址错误(404)"});
|
||||||
|
break
|
||||||
|
case 408:
|
||||||
|
rsp.errors.push({message: "请求超时(408)"});
|
||||||
|
break
|
||||||
|
case 500:
|
||||||
|
rsp.errors.push({message: "服务器内部错误(500)"});
|
||||||
|
break
|
||||||
|
case 501:
|
||||||
|
rsp.errors.push({message: "服务未实现(501)"});
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
rsp.errors.push({message: "请求错误(" + error.response.status + ")"});
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.reject(rsp);
|
||||||
|
});
|
||||||
|
jsonRequest = function (config) {
|
||||||
|
return instance.request({
|
||||||
|
params: {
|
||||||
|
method: config.method
|
||||||
|
},
|
||||||
|
url: "/ajax",
|
||||||
|
headers: {'Content-Type': 'text/plain'},
|
||||||
|
data: config.data
|
||||||
|
}).then(function (response) {
|
||||||
|
return Promise.resolve(response.data);
|
||||||
|
}, function (response) {
|
||||||
|
return Promise.resolve(response);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
fileRequest = function (config) {
|
||||||
|
return instance.request({
|
||||||
|
url: "/upload",
|
||||||
|
data: config.data,
|
||||||
|
headers: {'Content-Type': 'multipart/form-data'},
|
||||||
|
onUploadProgress: function (progressEvent) {
|
||||||
|
var complete = (progressEvent.loaded / progressEvent.total * 100 | 0) + '%'
|
||||||
|
nav.tip.show("上传中(" + complete + ")")
|
||||||
|
}
|
||||||
|
}).then(function (response) {
|
||||||
|
return Promise.resolve(response.data);
|
||||||
|
}, function (response) {
|
||||||
|
return Promise.resolve(response);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
window.ajax = {
|
||||||
|
example: function (data) {
|
||||||
|
return jsonRequest({
|
||||||
|
method: "ajax.example.example",
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
fileUpload: function (file) {
|
||||||
|
var fd = new FormData();
|
||||||
|
fd.append("file", file);
|
||||||
|
return fileRequest({
|
||||||
|
data: fd
|
||||||
|
})
|
||||||
|
},
|
||||||
|
newTableCreate: function (data) {
|
||||||
|
return jsonRequest({
|
||||||
|
method:"ajax.filemgr.new.table.create",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
newTableDelete: function (data) {
|
||||||
|
return jsonRequest({
|
||||||
|
method:"ajax.filemgr.new.table.delete",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
newTableUpdate: function (data) {
|
||||||
|
return jsonRequest({
|
||||||
|
method:"ajax.filemgr.new.table.update",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
newTableFind: function (data) {
|
||||||
|
return jsonRequest({
|
||||||
|
method:"ajax.filemgr.new.table.find",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
newTableGet: function(data) {
|
||||||
|
return jsonRequest({
|
||||||
|
method:"ajax.filemgr.new.table.get",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
@ -0,0 +1,249 @@
|
|||||||
|
<head>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
width: 700px;
|
||||||
|
margin: 50px auto;
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code {
|
||||||
|
font-weight: 500;
|
||||||
|
top: 100px;
|
||||||
|
left: 400px;
|
||||||
|
text-align: center;
|
||||||
|
width: 300px;
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-family: 'Varela Round', sans-serif;
|
||||||
|
font-size: 60px;
|
||||||
|
color: #6bbee0;
|
||||||
|
letter-spacing: 3px;
|
||||||
|
text-shadow: 0 0 5px #78d0ec;
|
||||||
|
animation: flux 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #505050;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message2 {
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #505050;
|
||||||
|
font-weight: 300;
|
||||||
|
width: 360px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.door-frame {
|
||||||
|
height: 340px;
|
||||||
|
width: 220px;
|
||||||
|
border-radius: 90px 90px 0 0;
|
||||||
|
background-color: #8594A5;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.door {
|
||||||
|
height: 280px;
|
||||||
|
width: 170px;
|
||||||
|
border-radius: 70px 70px 0 0;
|
||||||
|
background-color: #A0AEC0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eye {
|
||||||
|
top: 15px;
|
||||||
|
left: 25px;
|
||||||
|
height: 5px;
|
||||||
|
width: 15px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: white;
|
||||||
|
animation: eye 7s ease-in-out infinite;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eye2 {
|
||||||
|
left: 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window {
|
||||||
|
height: 40px;
|
||||||
|
width: 130px;
|
||||||
|
background-color: #1C2127;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 80px auto;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaf {
|
||||||
|
height: 40px;
|
||||||
|
width: 130px;
|
||||||
|
background-color: #8594A5;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 80px auto;
|
||||||
|
animation: leaf 7s infinite;
|
||||||
|
transform-origin: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handle {
|
||||||
|
height: 8px;
|
||||||
|
width: 30px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #EBF3FC;
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 195px;
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rectangle {
|
||||||
|
height: 60px;
|
||||||
|
width: 20px;
|
||||||
|
background-color: #CBD8E6;
|
||||||
|
border-radius: 4px;
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 160px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message3 {
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.login {
|
||||||
|
font-size: 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: rgba(0, 130, 192, 0.69);
|
||||||
|
}
|
||||||
|
|
||||||
|
a.login:hover {
|
||||||
|
color: #0074c0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes leaf {
|
||||||
|
0% {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
5% {
|
||||||
|
transform: scaleX(0.2);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: scaleX(0.2);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes eye {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(0)
|
||||||
|
}
|
||||||
|
5% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
15% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0)
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
transform: translateX(15px)
|
||||||
|
}
|
||||||
|
35% {
|
||||||
|
transform: translateX(15px)
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
transform: translateX(-15px)
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
transform: translateX(-15px)
|
||||||
|
}
|
||||||
|
65% {
|
||||||
|
transform: translateX(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flux {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
text-shadow: 0 0 5px #00FFC6, 0 0 15px #00FFC6, 0 0 50px #00FFC6, 0 0 50px #00FFC6, 0 0 2px #B9FFE8, 2px 2px 3px #12E29C;
|
||||||
|
color: #4BFFEF;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
text-shadow: 0 0 3px #00B58D, 0 0 7px #00B58D, 0 0 25px #00B58D, 0 0 25px #00B58D, 0 0 2px #00B58D, 2px 2px 3px #006A60;
|
||||||
|
color: #63D3AE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
window.onload = function () {
|
||||||
|
var count = 4;
|
||||||
|
|
||||||
|
function go() {
|
||||||
|
if (count > 0) {
|
||||||
|
var e = document.getElementById("timer");
|
||||||
|
e.innerHTML = count + " 秒后自动跳转登录页"
|
||||||
|
count--;
|
||||||
|
} else {
|
||||||
|
location.href = '${Uri.getUrl("/login")}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(go, 1000);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="box">
|
||||||
|
<div class="container">
|
||||||
|
<div class="door-frame">
|
||||||
|
<div class="door">
|
||||||
|
<div class="rectangle">
|
||||||
|
</div>
|
||||||
|
<div class="handle">
|
||||||
|
</div>
|
||||||
|
<div class="window">
|
||||||
|
<div class="eye">
|
||||||
|
</div>
|
||||||
|
<div class="eye eye2">
|
||||||
|
</div>
|
||||||
|
<div class="leaf">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="code">403</div>
|
||||||
|
<div class="message">您没有足够的权限哦!</div>
|
||||||
|
<div class="message2">您正在试图访问一个没有事先授权的页面.或登录已失效。</div>
|
||||||
|
<div class="message3" id="timer">5 秒后自动跳转登录页</div>
|
||||||
|
<a class="login" href="${Uri.getUrl("/login")}">立即跳转</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,40 @@
|
|||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
html,body{
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.box{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
.box a{
|
||||||
|
color: #c38168;
|
||||||
|
line-height: 18px;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.box::-webkit-scrollbar {/*滚动条整体样式*/
|
||||||
|
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
.box::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
|
||||||
|
border-radius: 10px;
|
||||||
|
-webkit-box-shadow: inset 0 0 5px rgba(73, 73, 73, 0.2);
|
||||||
|
background: #828282;
|
||||||
|
}
|
||||||
|
.box::-webkit-scrollbar-track {/*滚动条里面轨道*/
|
||||||
|
-webkit-box-shadow: inset 0 0 5px rgba(125, 125, 125, 0.2);
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #EDEDED;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<p>
|
||||||
|
${msg}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
<div style="height: 50px;background-color: #303133">
|
||||||
|
<center>
|
||||||
|
<h3 style="color: #ffffff">------------------------------this is footer html------------------------------</h3>
|
||||||
|
</center>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,119 @@
|
|||||||
|
<div id="header">
|
||||||
|
<div class="logo">
|
||||||
|
<img @click="this.nav.toHome()" src="${Uri.getUrl('/static/img/logo.png')}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a class="home" href="${Uri.getUrl('/')}">Home</a>
|
||||||
|
|
||||||
|
<div class="menu">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="${Uri.getUrl('/1')}">首页</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="${Uri.getUrl('/2')}">工作台</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="${Uri.getUrl('/3')}">消息中心</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="${Uri.getUrl('/4')}">关于我</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<style>
|
||||||
|
#header {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #2a2a2a;
|
||||||
|
box-shadow: 0px 2px 8px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .logo {
|
||||||
|
display: inline-block;
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
margin-left: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .logo img {
|
||||||
|
width: 50%;
|
||||||
|
height: 50%;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home {
|
||||||
|
display: inline-block;
|
||||||
|
color: #ffffff;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home:hover {
|
||||||
|
color: #ffffff;
|
||||||
|
transform: translate(2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .menu {
|
||||||
|
display: inline-block;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .menu ul {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .menu ul li {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .menu ul li a {
|
||||||
|
color: #ffffff;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
margin: 0px 15px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .menu ul li a:after {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
background: #ffffff;
|
||||||
|
width: 0%;
|
||||||
|
height: 2px;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 2px;
|
||||||
|
left: 50%;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .menu ul li a img {
|
||||||
|
margin-top: 8px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .menu ul li a:hover:after {
|
||||||
|
width: 100%;
|
||||||
|
left: 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .tx {
|
||||||
|
display: inline-block;
|
||||||
|
float: right;
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .tx img {
|
||||||
|
width: 50%;
|
||||||
|
height: 50%;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,233 @@
|
|||||||
|
<script>
|
||||||
|
window.nav = new Vue({
|
||||||
|
data: {
|
||||||
|
activeIndex: 'home',
|
||||||
|
contextPath: '${contextPath?default("")}',
|
||||||
|
homePath: '${homePath?default("")}',
|
||||||
|
loadingTip: '',
|
||||||
|
loadingBar: '',
|
||||||
|
tip: {
|
||||||
|
show: function (msg) {
|
||||||
|
var message = "<i class='el-icon-loading'></i> 正在加载 ..."
|
||||||
|
if (msg) {
|
||||||
|
message = "<i class='el-icon-loading'></i> " + msg
|
||||||
|
}
|
||||||
|
if (!nav.loadingTip) {
|
||||||
|
nav.loadingTip = nav.$message({
|
||||||
|
type: '',
|
||||||
|
duration: 0,
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
message: message
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
nav.loadingTip.message = message;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close: function () {
|
||||||
|
if (nav.loadingTip) {
|
||||||
|
nav.loadingTip.close();
|
||||||
|
nav.loadingTip = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bar: {
|
||||||
|
show: function () {
|
||||||
|
if (!nav.loadingBar) {
|
||||||
|
nav.loadingBar = nav.$message({
|
||||||
|
type: '',
|
||||||
|
duration: 0,
|
||||||
|
customClass: 'loading-bar',
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
message: '<i class="bar" style="width: 90%"></i>'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
nav.loadingBar.message = '<i class="bar" style="width: 90%"></i>'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
finish: function () {
|
||||||
|
if (nav.loadingBar) {
|
||||||
|
nav.loadingBar.message = '<i class="bar" style="width: 100%"></i>'
|
||||||
|
setTimeout(function(){
|
||||||
|
if (nav.loadingBar) {
|
||||||
|
nav.loadingBar.close();
|
||||||
|
nav.loadingBar = '';
|
||||||
|
}
|
||||||
|
},500);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
if (nav.loadingBar) {
|
||||||
|
nav.loadingBar.message = '<i class="bar error" style="width: 100%"></i>'
|
||||||
|
setTimeout(function(){
|
||||||
|
if(nav.loadingBar){
|
||||||
|
nav.loadingBar.close();
|
||||||
|
nav.loadingBar = '';
|
||||||
|
}
|
||||||
|
},500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
i: function (message, callback) {
|
||||||
|
this.$message({
|
||||||
|
type: "info",
|
||||||
|
showClose: true,
|
||||||
|
message: message,
|
||||||
|
duration: 1500,
|
||||||
|
onClose: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
e: function (message, callback) {
|
||||||
|
this.$message({
|
||||||
|
type: "error",
|
||||||
|
showClose: true,
|
||||||
|
message: message,
|
||||||
|
duration: 1500,
|
||||||
|
onClose: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
w: function (message, callback) {
|
||||||
|
this.$message({
|
||||||
|
type: "warning",
|
||||||
|
showClose: true,
|
||||||
|
message: message,
|
||||||
|
duration: 1500,
|
||||||
|
onClose: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
s: function (message, callback) {
|
||||||
|
this.$message({
|
||||||
|
type: "success",
|
||||||
|
showClose: true,
|
||||||
|
message: message,
|
||||||
|
duration: 1500,
|
||||||
|
onClose: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
toOpen: function (url) {
|
||||||
|
nav.tip.show();
|
||||||
|
var url = url.substring(0, 1) == "/" ? url.substring(1) : url;
|
||||||
|
$("body").append($("<a id='wb-open' href='" + this.contextPath + "/" + url + "' target='_self' style='dispaly:none;'></a>"))
|
||||||
|
document.getElementById("wb-open").click();
|
||||||
|
$("#wb-open").remove();
|
||||||
|
},
|
||||||
|
toOpenNew: function (url) {
|
||||||
|
var url = url.substring(0, 1) == "/" ? url.substring(1) : url;
|
||||||
|
$("body").append($("<a id='wb-open' href='" + this.contextPath + "/" + url + "' target='_blank' style='dispaly:none;'></a>"))
|
||||||
|
document.getElementById("wb-open").click();
|
||||||
|
$("#wb-open").remove();
|
||||||
|
},
|
||||||
|
toHome: function () {
|
||||||
|
nav.tip.show();
|
||||||
|
location.href = this.contextPath + "/"
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 滚动屏蔽至顶部
|
||||||
|
*/
|
||||||
|
scrollToTop: function () {
|
||||||
|
var distance = document.documentElement.scrollTop || document.body.scrollTop;
|
||||||
|
var step = distance / 10;
|
||||||
|
|
||||||
|
(function jump() {
|
||||||
|
if (distance > 0) {
|
||||||
|
distance -= step;
|
||||||
|
window.scrollTo(0, distance);
|
||||||
|
setTimeout(jump, 10)
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 控制任一目标滚动到顶部
|
||||||
|
* select jquery对象
|
||||||
|
*/
|
||||||
|
scrollToTop: function (select) {
|
||||||
|
var distance = $(select).scrollTop();
|
||||||
|
var step = distance / 10;
|
||||||
|
|
||||||
|
(function jump() {
|
||||||
|
if (distance > 0) {
|
||||||
|
distance -= step;
|
||||||
|
$(select).scrollTop(distance);
|
||||||
|
setTimeout(jump, 10)
|
||||||
|
} else {
|
||||||
|
$(select).scrollTop(distance);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取url参数
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
window.location.getParam = function (key) {
|
||||||
|
var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
|
||||||
|
var r = window.location.search.substr(1).match(reg);
|
||||||
|
if (r != null) {
|
||||||
|
return decodeURIComponent(r[2]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 打开新标签
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
window.location.open = function (url) {
|
||||||
|
$("body").append($("<a id='wb-open' href='" + url + "' target='_blank' style='dispaly:none;'></a>"))
|
||||||
|
document.getElementById("wb-open").click();
|
||||||
|
$("#wb-open").remove();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 日期格式化
|
||||||
|
*/
|
||||||
|
Date.prototype.format = function (format) {
|
||||||
|
var o = {
|
||||||
|
"M+": this.getMonth() + 1, //month
|
||||||
|
"d+": this.getDate(), //day
|
||||||
|
"h+": this.getHours(), //hour
|
||||||
|
"m+": this.getMinutes(), //minute
|
||||||
|
"s+": this.getSeconds(), //second
|
||||||
|
"q+": Math.floor((this.getMonth() + 3) / 3), //quarter
|
||||||
|
"S": this.getMilliseconds() //millisecond
|
||||||
|
}
|
||||||
|
if (/(y+)/.test(format)) format = format.replace(RegExp.$1,
|
||||||
|
(this.getFullYear() + "").substr(4 - RegExp.$1.length));
|
||||||
|
for (var k in o)if (new RegExp("(" + k + ")").test(format))
|
||||||
|
format = format.replace(RegExp.$1,
|
||||||
|
RegExp.$1.length == 1 ? o[k] :
|
||||||
|
("00" + o[k]).substr(("" + o[k]).length));
|
||||||
|
return format;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 数组移除
|
||||||
|
*/
|
||||||
|
Array.prototype.remove = function (val) {
|
||||||
|
var index = this.indexOf(val);
|
||||||
|
if (index > -1) {
|
||||||
|
this.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 数组替换
|
||||||
|
*/
|
||||||
|
Array.prototype.replace = function (val, obj) {
|
||||||
|
var index = this.indexOf(val);
|
||||||
|
if (index > -1) {
|
||||||
|
this.splice(index, 1, obj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 数组位置调整
|
||||||
|
*/
|
||||||
|
Array.prototype.exchange = function (val1, val2) {
|
||||||
|
if (val1 < 0 || val2 < 0 || val2 >= this.length || val1 >= this.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var o1 = this[val1];
|
||||||
|
var o2 = this[val2];
|
||||||
|
this.splice(val1, 1, o2);
|
||||||
|
this.splice(val2, 1, o1);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
<link href="${Uri.getUrl('/static/img/favicon.ico')}" rel="Shortcut Icon" type="image/x-icon"/>
|
||||||
|
<script src="${Uri.getUrl('/static/dist/lib.min.js')}" type="text/javascript"></script>
|
||||||
|
<link href="${Uri.getUrl('/static/dist/lib.min.css')}" rel="stylesheet"/>
|
||||||
|
<script src="${Uri.getUrl('/static/js/ajax.js')}" type="text/javascript"></script>
|
||||||
|
<link href="${Uri.getUrl('/static/css/base.css')}" rel="stylesheet"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<#include Layout.setControl("macro")/>
|
||||||
|
<#include Layout.setControl("nav")/>
|
||||||
|
<div class="wb-layout-title-fix">
|
||||||
|
<div class="wb-head">
|
||||||
|
<#include Layout.setControl("header")/>
|
||||||
|
</div>
|
||||||
|
<div class="wb-body">
|
||||||
|
<#include Layout.setScreen()/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>文件管理</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
|
||||||
|
<link href="${Uri.getUrl('/static/img/favicon.ico')}" rel="Shortcut Icon" type="image/x-icon"/>
|
||||||
|
<script src="${Uri.getUrl('/static/dist/lib.min.js')}" type="text/javascript"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<#include Layout.setScreen()/>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<title>Mint UI</title>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
<router-link to="/">首页</router-link>
|
||||||
|
<router-link to="/next">next</router-link>
|
||||||
|
<transition name="wb-zoom-in-top">
|
||||||
|
<router-view></router-view>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template id="home"><div>home</div></template>
|
||||||
|
<template id="next"><div>next</div></template>
|
||||||
|
<script src="${Uri.getUrl('/static/lib/vue/vue.min.js')}" type="text/javascript"></script>
|
||||||
|
<script src="${Uri.getUrl('/static/lib/vue/vue-router.min.js')}" type="text/javascript"></script>
|
||||||
|
<script src="${Uri.getUrl('/static/lib/fastclick.js')}" type="text/javascript"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var router = new VueRouter({
|
||||||
|
routes:[
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'home',
|
||||||
|
component:Vue.extend({template: '#home'})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/next',
|
||||||
|
name: 'next',
|
||||||
|
component:Vue.extend({template: '#next'})
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
var app = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
router:router
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<div id="app" v-cloak>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
var app = new Vue({
|
||||||
|
el: "#app",
|
||||||
|
data: {},
|
||||||
|
methods: {},
|
||||||
|
created: function () {
|
||||||
|
},
|
||||||
|
mounted: function () {
|
||||||
|
},
|
||||||
|
watch: {}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,25 @@
|
|||||||
|
package xyz.wbsite.config;
|
||||||
|
|
||||||
|
import xyz.wbsite.framework.base.Token;
|
||||||
|
import xyz.wbsite.framework.springmvc.GlobalHandlerInterceptor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.filter.CharacterEncodingFilter;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class TestConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Token getTestToken() {
|
||||||
|
Token token = new Token();
|
||||||
|
token.setId(-1);
|
||||||
|
token.setUserId(-1);
|
||||||
|
token.setUserName("system");
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
# 开发环境
|
||||||
|
server.port=8080
|
||||||
|
server.servlet.context-path=/
|
||||||
|
spring.mvc.static-path-pattern=/static/**
|
||||||
|
spring.resources.static-locations=classpath:static/
|
||||||
|
spring.application.name=SpringBoot
|
||||||
|
# 编码配置
|
||||||
|
spring.http.encoding.force=true
|
||||||
|
spring.http.encoding.charset=UTF-8
|
||||||
|
spring.http.encoding.enabled=true
|
||||||
|
server.tomcat.uri-encoding=UTF-8
|
||||||
|
# 根路径、欢迎页
|
||||||
|
web.welcome.page = index
|
||||||
|
# 排除的不需要验证的URL
|
||||||
|
web.url.excluded = /static/**,/open/**,/api,/index,/,/login
|
||||||
|
web.url.authorization = /**
|
||||||
|
# 默认的登录URL
|
||||||
|
web.url.login = /login
|
||||||
|
# 日志配置
|
||||||
|
logging.config=classpath:logback-config.xml
|
||||||
|
# 热部署生效
|
||||||
|
spring.devtools.restart.enabled=true
|
||||||
|
# mysql
|
||||||
|
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
|
||||||
|
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8
|
||||||
|
spring.datasource.username=test
|
||||||
|
spring.datasource.password=123456
|
||||||
|
# mybatis
|
||||||
|
mybatis.mapper-locations=classpath:**/mpr/*.xml
|
||||||
|
# pagehelper
|
||||||
|
pagehelper.autoRuntimeDialect=true
|
||||||
|
pagehelper.reasonable=true
|
||||||
|
pagehelper.supportMethodsArguments=true
|
||||||
|
pagehelper.params=count=countSql
|
||||||
|
# freemarker
|
||||||
|
spring.freemarker.enabled=true
|
||||||
|
spring.freemarker.allow-request-override=false
|
||||||
|
spring.freemarker.cache=true
|
||||||
|
spring.freemarker.check-template-location=true
|
||||||
|
spring.freemarker.charset=UTF-8
|
||||||
|
spring.freemarker.content-type=text/html
|
||||||
|
spring.freemarker.expose-request-attributes=false
|
||||||
|
spring.freemarker.expose-session-attributes=false
|
||||||
|
spring.freemarker.expose-spring-macro-helpers=false
|
||||||
|
spring.freemarker.settings.template_update_delay=1
|
||||||
|
spring.freemarker.settings.locale=zh_CN
|
||||||
|
spring.freemarker.settings.datetime_format=yyyy-MM-dd
|
||||||
|
spring.freemarker.settings.date_format=yyyy-MM-dd
|
||||||
|
spring.freemarker.settings.number_format=#.##
|
||||||
|
spring.freemarker.settings.classic_compatible=true
|
||||||
|
spring.freemarker.settings.whitespace_stripping=true
|
||||||
|
spring.freemarker.settings.url_escaping_charset=utf-8
|
||||||
|
# 文件上传配置
|
||||||
|
spring.servlet.multipart.resolveLazily = true
|
||||||
|
spring.servlet.multipart.max-file-size=100Mb
|
||||||
|
spring.servlet.multipart.max-request-size=100Mb
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||||
|
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
debug级别及以上
|
||||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
|
<level>DEBUG</level>
|
||||||
|
</filter>
|
||||||
|
<encoder>
|
||||||
|
<pattern>%highlight(%d{yyyy-MM-dd HH:mm:ss.SSS} [%-4level] [%thread] [%logger{36}-%method] %ex %msg%n)</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<logger name="java.sql" level="INFO"></logger>
|
||||||
|
|
||||||
|
<!-- 日志总入口 -->
|
||||||
|
<root level="DEBUG">
|
||||||
|
<appender-ref ref="Console"/>
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
||||||
Loading…
Reference in new issue