parent
a3c7bcc65b
commit
3156b6e344
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="admin" />
|
||||
<module name="nginx-admin" />
|
||||
<module name="wsqlite" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
<bytecodeTargetLevel target="1.8">
|
||||
<module name="admin" target="1.8" />
|
||||
<module name="nginx-admin" target="1.8" />
|
||||
<module name="wsqlite" target="1.8" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,159 @@
|
||||
<?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>xyz.wbsite</groupId>
|
||||
<artifactId>nginx-admin</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>xyz.wbsite</groupId>
|
||||
<artifactId>admin</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<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>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>xyz.wbsite</groupId>
|
||||
<artifactId>wsqlite</artifactId>
|
||||
</dependency>
|
||||
|
||||
<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>
|
||||
|
||||
<!-- mybatis 分页插件 -->
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</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>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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>
|
||||
</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>
|
||||
</project>
|
@ -0,0 +1,21 @@
|
||||
package com.example;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableAutoConfiguration
|
||||
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,124 @@
|
||||
package com.example.action;
|
||||
|
||||
import com.example.module.admin.mgr.MappingManager;
|
||||
import com.example.module.admin.req.*;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import com.example.frame.utils.LocalData;
|
||||
import com.example.frame.utils.MapperUtil;
|
||||
import com.example.frame.utils.Message;
|
||||
import com.example.frame.base.BaseResponse;
|
||||
import com.example.frame.base.ErrorType;
|
||||
import com.example.frame.base.Token;
|
||||
import com.example.frame.utils.LogUtil;
|
||||
import com.example.frame.base.Error;
|
||||
|
||||
@Controller
|
||||
public class AjaxController {
|
||||
|
||||
@Autowired
|
||||
private MappingManager mappingManager;
|
||||
|
||||
@RequestMapping("/ajax")
|
||||
@ResponseBody
|
||||
public BaseResponse ajax(@RequestParam("method") String method, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
BaseResponse baseResponse = new BaseResponse();
|
||||
String jsonString = null;
|
||||
try {
|
||||
if (method == null) {
|
||||
baseResponse.addError(new Error(ErrorType.BUSINESS_ERROR, "请求方法不能为空!"));
|
||||
return baseResponse;
|
||||
}
|
||||
Token token = LocalData.getToken();
|
||||
if (token == null) {
|
||||
token = LocalData.getTempToken();
|
||||
}
|
||||
if (!token.hasResource(method)) {
|
||||
baseResponse.addError(new Error(ErrorType.BUSINESS_ERROR, "无权调用该接口!"));
|
||||
return baseResponse;
|
||||
}
|
||||
|
||||
InputStreamReader isr = new InputStreamReader(request.getInputStream(), "UTF-8");
|
||||
BufferedReader in = new BufferedReader(isr);
|
||||
jsonString = in.readLine();
|
||||
|
||||
switch (method) {
|
||||
// 示例
|
||||
case "ajax.example.example":
|
||||
break;
|
||||
// 创建映射
|
||||
case "ajax.admin.mapping.create":
|
||||
baseResponse = createMapping(jsonString, token);
|
||||
break;
|
||||
// 删除映射
|
||||
case "ajax.admin.mapping.delete":
|
||||
baseResponse = deleteMapping(jsonString, token);
|
||||
break;
|
||||
// 修改映射
|
||||
case "ajax.admin.mapping.update":
|
||||
baseResponse = updateMapping(jsonString, token);
|
||||
break;
|
||||
// 查询映射
|
||||
case "ajax.admin.mapping.find":
|
||||
baseResponse = findMapping(jsonString, token);
|
||||
break;
|
||||
default:
|
||||
baseResponse.addError(ErrorType.INVALID_PARAMETER, Message.NOT_EXIST_METHOD);
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
baseResponse.addError(ErrorType.SYSTEM_ERROR, Message.ERROR_500);
|
||||
LogUtil.dumpException(ex);
|
||||
} finally {
|
||||
if (baseResponse.hasError()) {
|
||||
LogUtil.e("请求方法" + method + ", 请求参数:" + jsonString);
|
||||
LogUtil.e("返回结果包含异常" + MapperUtil.toJson(baseResponse));
|
||||
}
|
||||
}
|
||||
return baseResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建映射
|
||||
*/
|
||||
private BaseResponse createMapping(String jsonString, Token token) {
|
||||
MappingCreateRequest request = MapperUtil.toJava(jsonString, MappingCreateRequest.class);
|
||||
return mappingManager.create(request, token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除映射
|
||||
*/
|
||||
private BaseResponse deleteMapping(String jsonString, Token token) {
|
||||
MappingDeleteRequest request = MapperUtil.toJava(jsonString, MappingDeleteRequest.class);
|
||||
return mappingManager.delete(request, token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改映射
|
||||
*/
|
||||
private BaseResponse updateMapping(String jsonString, Token token) {
|
||||
MappingUpdateRequest request = MapperUtil.toJava(jsonString, MappingUpdateRequest.class);
|
||||
return mappingManager.update(request, token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询映射
|
||||
*/
|
||||
private BaseResponse findMapping(String jsonString, Token token) {
|
||||
MappingFindRequest request = MapperUtil.toJava(jsonString, MappingFindRequest.class);
|
||||
return mappingManager.find(request, token);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.example.action.control;
|
||||
|
||||
import com.example.frame.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 com.example.action.control;
|
||||
|
||||
import com.example.frame.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 com.example.action.screen;
|
||||
|
||||
import com.example.frame.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,88 @@
|
||||
package com.example.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 com.example.frame.base.Token;
|
||||
import com.example.frame.utils.CookieUtil;
|
||||
import com.example.frame.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;
|
||||
|
||||
@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/.*\\.htm");
|
||||
LocalData.setToken(token1);
|
||||
}
|
||||
|
||||
// 授权
|
||||
Token token_ = LocalData.getToken();
|
||||
if (token_.hasResource(request.getServletPath())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package com.example.frame.base;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Base - 基类
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
|
||||
public class BaseEntity implements Serializable {
|
||||
|
||||
/**
|
||||
* 行版本
|
||||
*/
|
||||
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,29 @@
|
||||
package com.example.frame.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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.example.frame.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 com.example.frame.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 com.example.frame.base;
|
||||
|
||||
/**
|
||||
* BaseRequest - 基类
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
public class BaseRequest {
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.example.frame.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 com.example.frame.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 com.example.frame.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 com.example.frame.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 com.example.frame.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 com.example.frame.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 com.example.frame.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 com.example.frame.base;
|
||||
|
||||
/**
|
||||
* SortTypeEnum - 排序方式
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
public enum SortType {
|
||||
|
||||
//升序
|
||||
ASC,
|
||||
|
||||
//降序
|
||||
DESC
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package com.example.frame.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,95 @@
|
||||
package com.example.frame.freemarker;
|
||||
|
||||
import java.io.File;
|
||||
import com.example.config.ActionConfig;
|
||||
import freemarker.template.TemplateModelException;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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 com.example.frame.base.Control;
|
||||
import com.example.frame.utils.LocalData;
|
||||
|
||||
/**
|
||||
* 布局帮助类
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
@Component
|
||||
public class Layout {
|
||||
|
||||
@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 = LocalData.getTarget();
|
||||
servletPath = servletPath.replaceAll("^/", "");
|
||||
|
||||
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(ActionConfig.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 com.example.frame.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,110 @@
|
||||
package com.example.frame.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;
|
||||
}
|
||||
}
|
@ -0,0 +1,497 @@
|
||||
package com.example.frame.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;
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.example.frame.utils;
|
||||
|
||||
import com.example.frame.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 Token temp = null;
|
||||
|
||||
private static Token system = null;
|
||||
|
||||
static {
|
||||
// 组装临时Token和系统Token
|
||||
temp = new Token();
|
||||
temp.setId(-1);
|
||||
temp.setUserId(-1);
|
||||
temp.setUserName("游客");
|
||||
temp.putResource("/");
|
||||
temp.putResource("/ajax");
|
||||
temp.putResource("/upload");
|
||||
temp.putResource("/index.htm");
|
||||
temp.putResource("/home.htm");
|
||||
temp.putResource("/app.htm");
|
||||
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,58 @@
|
||||
package com.example.frame.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();
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
package com.example.frame.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<T> 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 com.example.frame.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,117 @@
|
||||
package com.example.frame.utils;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* 程序操作工具
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
public class ProcessUtil {
|
||||
/**
|
||||
* 启动windows系统下的exe文件
|
||||
* @param path 可执行exe文件路径
|
||||
*/
|
||||
public static void execExe(String path) {
|
||||
Runtime rn = Runtime.getRuntime();
|
||||
Process p = null;
|
||||
try {
|
||||
p = rn.exec(path);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error exec!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行windows批处理文件路
|
||||
* @param path 可执行批处理文件路径
|
||||
*/
|
||||
public static void execBat(String path) {
|
||||
Runtime rn = Runtime.getRuntime();
|
||||
Process p = null;
|
||||
try {
|
||||
p = rn.exec(path);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error exec!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行windows cmd命令
|
||||
* @param command cmd命令
|
||||
*/
|
||||
public static String execCmd(String command) {
|
||||
return exec("cmd /c " + command);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行运行环境命令
|
||||
* @param command cmd命令
|
||||
*/
|
||||
public static String exec(String command) {
|
||||
StringBuilder build = new StringBuilder();
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
Process process = null;
|
||||
try {
|
||||
process = runtime.exec(command);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
|
||||
String line = null;
|
||||
while ((line = br.readLine()) != null) {
|
||||
build.append(line);
|
||||
}
|
||||
process.destroy();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return build.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IOException
|
||||
* @desc 杀死进程
|
||||
* @author zp
|
||||
* @date 2018-3-29
|
||||
*/
|
||||
public static void killProc(String processName) throws IOException {
|
||||
if (processName != null && !"".equals(processName)) {
|
||||
execCmd("taskkill /F /IM " + processName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 判断进程是否开启
|
||||
* @author zp
|
||||
* @date 2018-3-29
|
||||
*/
|
||||
public static boolean findProcess(String processName) {
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
Process proc = Runtime.getRuntime().exec("tasklist -fi " + '"' + "imagename eq " + processName + '"');
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
|
||||
String line = null;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
if (line.contains(processName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return false;
|
||||
} finally {
|
||||
if (bufferedReader != null) {
|
||||
try {
|
||||
bufferedReader.close();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,308 @@
|
||||
package com.example.frame.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) {
|
||||
return sign2Base64(data, signPrivateKeyBase64);
|
||||
}
|
||||
|
||||
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 boolean doCheck(byte[] data, String sign) {
|
||||
return doCheck(data, sign, signPublicKeyBase64);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.example.frame.utils;
|
||||
|
||||
import com.example.frame.base.BaseRequest;
|
||||
import com.example.frame.base.BaseResponse;
|
||||
import com.example.frame.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,18 @@
|
||||
package com.example.frame.validation;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Constraint(validatedBy = DictValidator.class)
|
||||
public @interface Dict {
|
||||
String message() default "字典项错误";
|
||||
|
||||
String name() default "";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.example.frame.validation;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class DictValidator implements ConstraintValidator<Dict, String> {
|
||||
|
||||
private String name;
|
||||
|
||||
@Override
|
||||
public void initialize(Dict constraint) {
|
||||
name = constraint.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(String o, ConstraintValidatorContext constraintValidatorContext) {
|
||||
if (null == o) {
|
||||
return true;
|
||||
} else if (name == null) {
|
||||
constraintValidatorContext.disableDefaultConstraintViolation();
|
||||
constraintValidatorContext.buildConstraintViolationWithTemplate("字典名称为空").addConstraintViolation();
|
||||
return false;
|
||||
} else {
|
||||
// name 字典名称
|
||||
HashSet<String> codeSet = new HashSet();
|
||||
if (codeSet.contains(o)) {
|
||||
return true;
|
||||
} else {
|
||||
constraintValidatorContext.disableDefaultConstraintViolation();
|
||||
constraintValidatorContext.buildConstraintViolationWithTemplate("非法的字典[" + name + "]值").addConstraintViolation();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.example.module.admin.ent;
|
||||
|
||||
import com.example.frame.base.BaseEntity;
|
||||
|
||||
/**
|
||||
* MAPPING - 映射
|
||||
*
|
||||
* @author author
|
||||
* @version 0.0.1
|
||||
* @since 2019-09-28
|
||||
*/
|
||||
public class Mapping extends BaseEntity {
|
||||
|
||||
/**
|
||||
* ID - 主键
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* USERNAME - 用户名
|
||||
*/
|
||||
private String username;
|
||||
/**
|
||||
* PASSWORD - 用户密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.example.module.admin.mgr;
|
||||
|
||||
import com.example.module.admin.req.*;
|
||||
import com.example.module.admin.rsp.*;
|
||||
import com.example.frame.base.Token;
|
||||
|
||||
/**
|
||||
* 映射
|
||||
*
|
||||
* @author author
|
||||
* @version 0.0.1
|
||||
* @since 2019-09-28
|
||||
*/
|
||||
public interface MappingManager {
|
||||
|
||||
/**
|
||||
* 插入
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @param token 令牌
|
||||
* @return
|
||||
*/
|
||||
MappingCreateResponse create(MappingCreateRequest request, Token token);
|
||||
|
||||
/**
|
||||
* 逻辑删除
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @param token 令牌
|
||||
* @return
|
||||
*/
|
||||
MappingDeleteResponse delete(MappingDeleteRequest request, Token token);
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @param token 令牌
|
||||
* @return
|
||||
*/
|
||||
MappingUpdateResponse update(MappingUpdateRequest request, Token token);
|
||||
|
||||
/**
|
||||
* 查询
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @param token 令牌
|
||||
* @return
|
||||
*/
|
||||
MappingFindResponse find(MappingFindRequest request, Token token);
|
||||
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
package com.example.module.admin.mgr;
|
||||
|
||||
import com.example.frame.utils.IDgenerator;
|
||||
import com.example.frame.utils.Message;
|
||||
import com.example.frame.base.ErrorType;
|
||||
import com.example.frame.base.Token;
|
||||
import com.example.frame.utils.MapperUtil;
|
||||
import com.example.frame.utils.ValidationUtil;
|
||||
import com.example.module.admin.ent.Mapping;
|
||||
import com.example.module.admin.req.MappingCreateRequest;
|
||||
import com.example.module.admin.req.MappingDeleteRequest;
|
||||
import com.example.module.admin.req.MappingFindRequest;
|
||||
import com.example.module.admin.req.MappingUpdateRequest;
|
||||
import com.example.module.admin.rsp.MappingCreateResponse;
|
||||
import com.example.module.admin.rsp.MappingDeleteResponse;
|
||||
import com.example.module.admin.rsp.MappingFindResponse;
|
||||
import com.example.module.admin.rsp.MappingUpdateResponse;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.github.pagehelper.util.StringUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* MAPPING - 映射
|
||||
*
|
||||
* @author author
|
||||
* @version 0.0.1
|
||||
* @since 2019-09-28
|
||||
*/
|
||||
@Service
|
||||
public class MappingManagerImpl implements MappingManager {
|
||||
|
||||
/**
|
||||
* 插入
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @param token 令牌
|
||||
* @return 响应
|
||||
*/
|
||||
public MappingCreateResponse create(MappingCreateRequest request, Token token) {
|
||||
MappingCreateResponse response = new MappingCreateResponse();
|
||||
|
||||
ValidationUtil.validate(request, response);
|
||||
if (response.hasError()) {
|
||||
return response;
|
||||
}
|
||||
|
||||
long id = IDgenerator.nextId();
|
||||
Mapping entity = MapperUtil.map(request, Mapping.class);
|
||||
entity.setId(id);
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 逻辑删除
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @param token 令牌
|
||||
* @return 响应
|
||||
*/
|
||||
public MappingDeleteResponse delete(MappingDeleteRequest request, Token token) {
|
||||
MappingDeleteResponse response = new MappingDeleteResponse();
|
||||
|
||||
ValidationUtil.validate(request, response);
|
||||
if (response.hasError()) {
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @param token 令牌
|
||||
* @return 响应
|
||||
*/
|
||||
public MappingUpdateResponse update(MappingUpdateRequest request, Token token) {
|
||||
MappingUpdateResponse response = new MappingUpdateResponse();
|
||||
|
||||
ValidationUtil.validate(request, response);
|
||||
if (response.hasError()) {
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @param token 令牌
|
||||
* @return 响应
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public MappingFindResponse find(MappingFindRequest request, Token token) {
|
||||
MappingFindResponse response = new MappingFindResponse();
|
||||
|
||||
ValidationUtil.validate(request, response);
|
||||
if (response.hasError()) {
|
||||
return response;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.example.module.admin.req;
|
||||
|
||||
import com.example.frame.base.BaseRequest;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
/**
|
||||
* MappingCreateRequest - 映射新增
|
||||
*
|
||||
* @author author
|
||||
* @version 0.0.1
|
||||
* @since 2019-09-28
|
||||
*/
|
||||
public class MappingCreateRequest extends BaseRequest {
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@Length(min = 0, max = 100, message = "用户名长度不合法(0-100)")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
@Length(min = 0, max = 100, message = "用户密码长度不合法(0-100)")
|
||||
private String password;
|
||||
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.example.module.admin.req;
|
||||
|
||||
import com.example.frame.base.BaseUpdateRequest;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* MappingDeleteRequest - 映射删除
|
||||
*
|
||||
* @author author
|
||||
* @version 0.0.1
|
||||
* @since 2019-09-28
|
||||
*/
|
||||
public class MappingDeleteRequest extends BaseUpdateRequest {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空")
|
||||
private long id;
|
||||
|
||||
public long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.example.module.admin.req;
|
||||
|
||||
import com.example.frame.base.BaseFindRequest;
|
||||
|
||||
/**
|
||||
* MappingRequest - 映射查询
|
||||
*
|
||||
* @author author
|
||||
* @version 0.0.1
|
||||
* @since 2019-09-28
|
||||
*/
|
||||
public class MappingFindRequest extends BaseFindRequest {
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.example.module.admin.req;
|
||||
|
||||
import com.example.frame.base.BaseUpdateRequest;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
/**
|
||||
* MappingUpdateRequest - 映射更新
|
||||
*
|
||||
* @author author
|
||||
* @version 0.0.1
|
||||
* @since 2019-09-28
|
||||
*/
|
||||
public class MappingUpdateRequest extends BaseUpdateRequest {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为NULL")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@Length(min = 0, max = 100, message = "用户名长度不合法(0-100)")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
@Length(min = 0, max = 100, message = "用户密码长度不合法(0-100)")
|
||||
private String password;
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.example.module.admin.rsp;
|
||||
|
||||
import com.example.frame.base.BaseResponse;
|
||||
|
||||
/**
|
||||
* MappingCreateResponse - 映射
|
||||
*
|
||||
* @author author
|
||||
* @version 0.0.1
|
||||
* @since 2019-09-28
|
||||
*/
|
||||
public class MappingCreateResponse extends BaseResponse {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.example.module.admin.rsp;
|
||||
|
||||
import com.example.frame.base.BaseResponse;
|
||||
|
||||
/**
|
||||
* MappingDeleteResponse - 映射
|
||||
*
|
||||
* @author author
|
||||
* @version 0.0.1
|
||||
* @since 2019-09-28
|
||||
*/
|
||||
public class MappingDeleteResponse extends BaseResponse {
|
||||
|
||||
/**
|
||||
* 删除数目
|
||||
*/
|
||||
private Long result;
|
||||
|
||||
public Long getResult() {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
public void setResult(Long result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.example.module.admin.rsp;
|
||||
|
||||
|
||||
import com.example.frame.base.BaseFindResponse;
|
||||
import com.example.module.admin.ent.Mapping;
|
||||
|
||||
/**
|
||||
* MappingFindResponse - 映射
|
||||
*
|
||||
* @author author
|
||||
* @version 0.0.1
|
||||
* @since 2019-09-28
|
||||
*/
|
||||
public class MappingFindResponse extends BaseFindResponse<Mapping> {
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.example.module.admin.rsp;
|
||||
|
||||
import com.example.frame.base.BaseResponse;
|
||||
|
||||
/**
|
||||
* MappingUpdateResponse - 映射
|
||||
*
|
||||
* @author author
|
||||
* @version 0.0.1
|
||||
* @since 2019-09-28
|
||||
*/
|
||||
public class MappingUpdateResponse extends BaseResponse {
|
||||
|
||||
/**
|
||||
* 更新数目
|
||||
*/
|
||||
private Long result;
|
||||
|
||||
public Long getResult() {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
public void setResult(Long result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
# 开发环境
|
||||
server.port=8080
|
||||
server.servlet.context-path=/
|
||||
spring.mvc.static-path-pattern=/static/**
|
||||
spring.resources.static-locations=classpath:static/
|
||||
spring.application.name=EXAMPLE-WEB
|
||||
spring.main.banner-mode=CONSOLE
|
||||
spring.devtools.restart.enabled=true
|
||||
# 编码配置
|
||||
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.htm
|
||||
# 需要验证授权, 既访问时组装Token
|
||||
web.url.auth.included=/**
|
||||
# 不需要验证授权, 或该请求有自己的验证机制
|
||||
web.url.auth.excluded=/favicon.ico,/static/**,/api,/login.htm
|
||||
# 日志配置
|
||||
logging.path=D://
|
||||
logging.levels=DEBUG
|
||||
logging.config=classpath:logback-config.xml
|
||||
# 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&useSSL=false
|
||||
spring.datasource.username=test
|
||||
spring.datasource.password=123456
|
||||
# mybatis
|
||||
mybatis.mapper-locations=classpath:**/mpr/*.xml
|
||||
# pagehelper
|
||||
pagehelper.autoRuntimeDialect=true
|
||||
pagehelper.reasonable=false
|
||||
pagehelper.supportMethodsArguments=true
|
||||
pagehelper.params=count=countSql
|
||||
# jackson 相关配置
|
||||
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
|
||||
spring.jackson.time-zone=GMT+8
|
||||
spring.jackson.default-property-inclusion=use_defaults
|
||||
spring.jackson.mapper.sort-properties-alphabetically=true
|
||||
spring.jackson.deserialization.fail-on-unknown-properties=false
|
||||
# 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=false
|
||||
spring.servlet.multipart.max-file-size=100MB
|
||||
spring.servlet.multipart.max-request-size=100MB
|
@ -0,0 +1,63 @@
|
||||
# 生产环境
|
||||
server.port=80
|
||||
server.servlet.context-path=/
|
||||
spring.mvc.static-path-pattern=/static/**
|
||||
spring.resources.static-locations=classpath:static/
|
||||
spring.application.name=EXAMPLE-WEB
|
||||
spring.main.banner-mode=off
|
||||
spring.devtools.restart.enabled=false
|
||||
# 编码配置
|
||||
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.htm
|
||||
# 需要验证授权, 既访问时组装Token
|
||||
web.url.auth.included=/**
|
||||
# 不需要验证授权, 或该请求有自己的验证机制
|
||||
web.url.auth.excluded=/favicon.ico,/static/**,/api,/login.htm
|
||||
# 日志配置
|
||||
logging.path=/root/
|
||||
logging.levels=INFO
|
||||
logging.config=classpath:logback-config.xml
|
||||
# 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&useSSL=false
|
||||
spring.datasource.username=test
|
||||
spring.datasource.password=123456
|
||||
# mybatis
|
||||
mybatis.mapper-locations=classpath:**/mpr/*.xml
|
||||
# pagehelper
|
||||
pagehelper.autoRuntimeDialect=true
|
||||
pagehelper.reasonable=false
|
||||
pagehelper.supportMethodsArguments=true
|
||||
pagehelper.params=count=countSql
|
||||
# jackson 相关配置
|
||||
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
|
||||
spring.jackson.time-zone=GMT+8
|
||||
spring.jackson.default-property-inclusion=use_defaults
|
||||
spring.jackson.mapper.sort-properties-alphabetically=true
|
||||
spring.jackson.deserialization.fail-on-unknown-properties=false
|
||||
# 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=false
|
||||
spring.servlet.multipart.max-file-size=100MB
|
||||
spring.servlet.multipart.max-request-size=100MB
|
@ -0,0 +1,26 @@
|
||||
${AnsiColor.BRIGHT_YELLOW}
|
||||
/////////////////////////////////////////////////////////
|
||||
// _ooOoo_ //
|
||||
// o8888888o //
|
||||
// 88" . "88 //
|
||||
// (| ^_^ |) //
|
||||
// O\ = /O //
|
||||
// ____/`---'\____ //
|
||||
// .' \\| |// `. //
|
||||
// / \\||| : |||// \ //
|
||||
// / _||||| -:- |||||- \ //
|
||||
// | | \\\ - /// | | //
|
||||
// | \_| ''\---/'' | | //
|
||||
// \ .-\__ `-` ___/-. / //
|
||||
// ___`. .' /--.--\ `. . ___ //
|
||||
// ."" '< `.___\_<|>_/___.' >'"". //
|
||||
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
|
||||
// \ \ `-. \_ __\ /__ _/ .-` / / //
|
||||
// ========`-.____`-.___\_____/___.-`____.-'======== //
|
||||
// `=---=' //
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
佛祖保佑 永无BUG
|
||||
:: Spring Boot :: ${spring-boot.formatted-version} (${spring.profiles.active})
|
||||
|
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
<projectName>EXAMPLE-WEB</projectName>
|
||||
<projectBasePackage>com.example</projectBasePackage>
|
||||
<projectAuthor>author</projectAuthor>
|
||||
<modules>
|
||||
<module>
|
||||
<moduleComment>用户</moduleComment>
|
||||
<modulePrefix>SYS</modulePrefix>
|
||||
<moduleName>usermodel</moduleName>
|
||||
<hasSysFields>true</hasSysFields>
|
||||
<tables>
|
||||
<table create="true" delete="true" find="true" get="true" getAll="false" search="false" tableComment="映射" tableName="MAPPING" update="true">
|
||||
<fields>
|
||||
<field IsSystem="true" defaultValue="" fieldComment="主键" fieldLength="0" fieldName="ID" fieldType="Long" isMust="true" isPrimaryKey="true" isQuery="false" isSearch="false"/>
|
||||
<field IsSystem="false" defaultValue="NULL" fieldComment="用户名" fieldLength="100" fieldName="USERNAME" fieldType="String_var100" isMust="false" isPrimaryKey="false" isQuery="true" isSearch="false"/>
|
||||
<field IsSystem="false" defaultValue="NULL" fieldComment="用户密码" fieldLength="100" fieldName="PASSWORD" fieldType="String_var100" isMust="false" isPrimaryKey="false" isQuery="true" 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,17 @@
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for MAPPING - 映射
|
||||
-- ----------------------------
|
||||
CREATE TABLE `SYSMAPPING` (
|
||||
`ID` BIGINT(20) NOT NULL COMMENT '主键',
|
||||
`USERNAME` VARCHAR(100) COMMENT '用户名',
|
||||
`PASSWORD` VARCHAR(100) 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,22 @@
|
||||
/*
|
||||
Target : MYSQL
|
||||
Author
|
||||
Date: 2019-08-14
|
||||
*/
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for USER - 用户
|
||||
-- ----------------------------
|
||||
|
||||
CREATE TABLE `SYSUSER` (
|
||||
`ID` BIGINT(20) NOT NULL COMMENT '主键',
|
||||
`USERNAME` VARCHAR(100) COMMENT '用户名',
|
||||
`PASSWORD` VARCHAR(100) 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.levels"/>
|
||||
|
||||
<!-- 迭代日志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>
|
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cd %cd%
|
||||
start java -Dfile.encoding=UTF-8 -jar EXAMPLE-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 EXAMPLE-WEB-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
|
@ -0,0 +1,687 @@
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
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
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em
|
||||
}
|
||||
|
||||
button, input, optgroup, select, textarea {
|
||||
font-family: sans-serif;
|
||||
font-size: 100%;
|
||||
line-height: 1.15;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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: 0;
|
||||
left: 0;
|
||||
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
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,143 @@
|
||||
//创建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();
|
||||
try {//确保服务器正确返回Json
|
||||
if(response.data.errors.length > 0){
|
||||
console.error(response.data.errors)
|
||||
}
|
||||
nav.bar.finish();
|
||||
}catch (e){
|
||||
nav.bar.error();
|
||||
response.data = {errors: [{message: '服务器错误'}]};
|
||||
}
|
||||
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
|
||||
})
|
||||
},
|
||||
mappingCreate: function (data) {
|
||||
return jsonRequest({
|
||||
method:"ajax.admin.mapping.create",
|
||||
data: JSON.stringify(data),
|
||||
})
|
||||
},
|
||||
mappingDelete: function (data) {
|
||||
return jsonRequest({
|
||||
method:"ajax.admin.mapping.delete",
|
||||
data: JSON.stringify(data),
|
||||
})
|
||||
},
|
||||
mappingUpdate: function (data) {
|
||||
return jsonRequest({
|
||||
method:"ajax.admin.mapping.update",
|
||||
data: JSON.stringify(data),
|
||||
})
|
||||
},
|
||||
mappingFind: function (data) {
|
||||
return jsonRequest({
|
||||
method:"ajax.admin.mapping.find",
|
||||
data: JSON.stringify(data),
|
||||
})
|
||||
},
|
||||
mappingGet: function(data) {
|
||||
return jsonRequest({
|
||||
method:"ajax.admin.mapping.get",
|
||||
data: JSON.stringify(data),
|
||||
})
|
||||
},
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
import axios from 'axios'
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
|
||||
withCredentials: true, // send cookies when cross-domain requests
|
||||
method: 'post', // request method
|
||||
timeout: 5000 // request timeout
|
||||
})
|
||||
|
||||
// 添加请求拦截器
|
||||
service.interceptors.request.use(config => {
|
||||
// 在发送请求之前做些什么
|
||||
if (config.url === '/upload') {
|
||||
console.log()
|
||||
} else {
|
||||
console.log()
|
||||
}
|
||||
return config
|
||||
}, error => {
|
||||
// 对请求错误做些什么
|
||||
return Promise.reject(error)
|
||||
})
|
||||
|
||||
// 添加响应拦截器
|
||||
service.interceptors.response.use(response => {
|
||||
// 对响应数据做点什么
|
||||
return response
|
||||
}, 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)
|
||||
})
|
||||
export function jsonRequest(config) {
|
||||
return service.request({
|
||||
params: {
|
||||
method: config.method
|
||||
},
|
||||
url: '/ajax',
|
||||
headers: { 'Content-Type': 'text/plain' },
|
||||
data: config.data
|
||||
}).then(response => {
|
||||
return Promise.resolve(response.data)
|
||||
}, response => {
|
||||
return Promise.resolve(response)
|
||||
})
|
||||
}
|
||||
export function fileRequest(config) {
|
||||
return service.request({
|
||||
url: '/upload',
|
||||
data: config.data,
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
onUploadProgress: progressEvent => {
|
||||
console.log((progressEvent.loaded / progressEvent.total * 100 | 0) + '%')
|
||||
}
|
||||
}).then(response => {
|
||||
return Promise.resolve(response.data)
|
||||
}, response => {
|
||||
return Promise.resolve(response)
|
||||
})
|
||||
}
|
||||
|
||||
const ajax = {
|
||||
example: data => {
|
||||
return jsonRequest({
|
||||
method: 'ajax.example.example',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
fileUpload: file => {
|
||||
const fd = new FormData()
|
||||
fd.append('file', file)
|
||||
return fileRequest({
|
||||
data: fd
|
||||
})
|
||||
},
|
||||
mappingCreate: data => {
|
||||
return jsonRequest({
|
||||
method:'ajax.admin.mapping.create',
|
||||
data: JSON.stringify(data),
|
||||
})
|
||||
},
|
||||
mappingDelete: data => {
|
||||
return jsonRequest({
|
||||
method:'ajax.admin.mapping.delete',
|
||||
data: JSON.stringify(data),
|
||||
})
|
||||
},
|
||||
mappingUpdate: data => {
|
||||
return jsonRequest({
|
||||
method:'ajax.admin.mapping.update',
|
||||
data: JSON.stringify(data),
|
||||
})
|
||||
},
|
||||
mappingFind: data => {
|
||||
return jsonRequest({
|
||||
method:'ajax.admin.mapping.find',
|
||||
data: JSON.stringify(data),
|
||||
})
|
||||
},
|
||||
mappingGet: data => {
|
||||
return jsonRequest({
|
||||
method:'ajax.admin.mapping.get',
|
||||
data: JSON.stringify(data),
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
export default ajax
|
@ -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.htm")}';
|
||||
}
|
||||
}
|
||||
|
||||
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,160 @@
|
||||
<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);
|
||||
}
|
||||
})();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@ -0,0 +1,217 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; 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">
|
||||
<#--baseJs-->
|
||||
<script src="${Uri.getUrl('/static/dist/lib.min.js')}" type="text/javascript"></script>
|
||||
<#--移动端ui-->
|
||||
<script src="${Uri.getUrl('/static/dist/mint-ui.min.js')}" type="text/javascript"></script>
|
||||
<link href="${Uri.getUrl('/static/dist/mint-ui.min.css')}" rel="stylesheet"/>
|
||||
<#--ajax接口-->
|
||||
<script src="${Uri.getUrl('/static/js/ajax.js')}" type="text/javascript"></script>
|
||||
<style>
|
||||
* {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
html,body,#app{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.left-in-right-out-enter-active, .left-in-right-out-leave-active {
|
||||
transition: all 0.3s linear;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.left-in-right-out-enter {
|
||||
transform: translateX(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.left-in-right-out-leave-to {
|
||||
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%);
|
||||
}
|
||||
|
||||
.left-in-right-out-enter-active, .left-in-right-out-leave-active {
|
||||
transition: all 0.3s linear;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.left-in-right-out-enter {
|
||||
transform: translateX(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.left-in-right-out-leave-to {
|
||||
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%);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<#include Layout.setControl("mint-ui-extend")/>
|
||||
<div id="app">
|
||||
<transition :name="transitionName">
|
||||
<router-view></router-view>
|
||||
</transition>
|
||||
</div>
|
||||
|
||||
<template id="home">
|
||||
<div class="view">
|
||||
<mt-header title="Hello world">
|
||||
<router-link to="/" slot="left">
|
||||
<mt-button icon="back">返回</mt-button>
|
||||
</router-link>
|
||||
<mt-button icon="more" slot="right"></mt-button>
|
||||
</mt-header>
|
||||
<div class="content" style="text-align: center;padding-top: 200px">
|
||||
Hello world <router-link to="demo">demo</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template id="demo">
|
||||
<div class="view">
|
||||
<mt-header title="表单输入">
|
||||
<mt-button icon="back" slot="left" @click="back">关闭</mt-button>
|
||||
</mt-header>
|
||||
<div class="content" style="text-align: center;">
|
||||
<mt-header title="Mint-ui自带控件"></mt-header>
|
||||
<mt-field label="普通文字" placeholder="请输入用户名" v-model="field1"></mt-field>
|
||||
<mt-field label="邮箱地址" placeholder="请输入邮箱" type="email" v-model="field2"></mt-field>
|
||||
<mt-field label="用户密码" placeholder="请输入密码" type="password" v-model="field3"></mt-field>
|
||||
<mt-field label="手机号码" placeholder="请输入手机号" type="tel" v-model="field4"></mt-field>
|
||||
<mt-field label="网站链接" placeholder="请输入网址" type="url" v-model="field5"></mt-field>
|
||||
<mt-field label="数字输入" placeholder="请输入数字" type="number" v-model="field6"></mt-field>
|
||||
<mt-field label="生日日期" placeholder="请输入生日" type="date" v-model="field7"></mt-field>
|
||||
<mt-field label="多行文字" placeholder="多行文字" type="textarea" rows="2" v-model="field8"></mt-field>
|
||||
|
||||
<mt-header title="扩展控件"></mt-header>
|
||||
<wb-field-select label="文字选择" placeholder="请选择" :items="['男','女']" v-model="field10"></wb-field-select>
|
||||
<wb-field-dict label="字典选择" placeholder="请选择" :items="[{key:'1',value:'男'},{key:'2',value:'女'}]"
|
||||
v-model="field11"></wb-field-dict>
|
||||
<wb-field-date label="日期选择" placeholder="请选择" v-model="field12"></wb-field-date>
|
||||
<wb-field-time label="时间选择" placeholder="请选择" v-model="field13"></wb-field-time>
|
||||
<wb-field-datetime label="日期时间" placeholder="请选择" v-model="field14"></wb-field-datetime>
|
||||
<wb-field-cphm label="车牌号码" placeholder="车牌号" v-model="field15"></wb-field-cphm>
|
||||
|
||||
<wb-field-pictures label="选择照片" v-model="field16" @handle-file="handleFile"></wb-field-pictures>
|
||||
|
||||
<div style="padding: 10px">
|
||||
<mt-button type="primary" size="large" @click="doSearch()">打印类容</mt-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
var router = new VueRouter({
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: Vue.extend({template: '#home'})
|
||||
},
|
||||
{
|
||||
path: '/demo',
|
||||
name: 'demo',
|
||||
component: Vue.extend({
|
||||
template: '#demo',
|
||||
mounted: function () {
|
||||
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
field1: '',
|
||||
field2: '',
|
||||
field3: '',
|
||||
field4: '',
|
||||
field5: '',
|
||||
field6: '',
|
||||
field7: '',
|
||||
field8: '',
|
||||
field9: '',
|
||||
field10: '',
|
||||
field11: '',
|
||||
field12: '',
|
||||
field13: '',
|
||||
field14: '',
|
||||
field15: '',
|
||||
field16: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doSearch: function () {
|
||||
console.log(this.field10);
|
||||
console.log(this.field11);
|
||||
console.log(this.field12);
|
||||
console.log(this.field13);
|
||||
console.log(this.field14);
|
||||
console.log(this.field15);
|
||||
console.log(this.field16);
|
||||
},
|
||||
back: function () {
|
||||
if (window.android) {
|
||||
android.finish()
|
||||
} else {
|
||||
location.href = "${Uri.getUrl('/app/index.htm')}"
|
||||
}
|
||||
},
|
||||
handleFile: function (file, call) {
|
||||
//do upload
|
||||
console.log("正在上传文件" + file.name);
|
||||
if (true) {
|
||||
call.finish();
|
||||
} else {
|
||||
call.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
]
|
||||
});
|
||||
var app = new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
transitionName: ''
|
||||
},
|
||||
router: router,
|
||||
watch: {
|
||||
'$route': function (to, from) {
|
||||
this.transitionName = to.meta.index < from.meta.index ? 'left-in-right-out' : 'right-in-left-out'
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</html>
|
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<#--baseJs-->
|
||||
<script src="${Uri.getUrl('/static/dist/lib.min.js')}" type="text/javascript"></script>
|
||||
<#--element-ui-->
|
||||
<script src="${Uri.getUrl('/static/dist/index.min.js')}" type="text/javascript"></script>
|
||||
<link href="${Uri.getUrl('/static/dist/index.min.css')}" rel="stylesheet"/>
|
||||
<#--ajax接口-->
|
||||
<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")/>
|
||||
<#include Layout.setScreen()/>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<#--baseJs-->
|
||||
<script src="${Uri.getUrl('/static/dist/lib.min.js')}" type="text/javascript"></script>
|
||||
<#--element-ui-->
|
||||
<script src="${Uri.getUrl('/static/dist/index.min.js')}" type="text/javascript"></script>
|
||||
<link href="${Uri.getUrl('/static/dist/index.min.css')}" rel="stylesheet"/>
|
||||
</head>
|
||||
<body>
|
||||
<#include Layout.setScreen()/>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,19 @@
|
||||
<div id="app" v-cloak>
|
||||
|
||||
</div>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
<script>
|
||||
var app = new Vue({
|
||||
el: "#app",
|
||||
data: {},
|
||||
methods: {},
|
||||
filters: {},
|
||||
created: function () {
|
||||
},
|
||||
mounted: function () {
|
||||
},
|
||||
watch: {}
|
||||
})
|
||||
</script>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,342 @@
|
||||
<div id="index" v-cloak>
|
||||
<div id="aside">
|
||||
<el-menu
|
||||
:style="{width:(properties.isCollapse?'64px':'200px')}"
|
||||
:default-active="properties.defaultActive"
|
||||
@open="handleOpen"
|
||||
@close="handleClose"
|
||||
@select="handleSelect"
|
||||
:unique-opened="properties.uniqueOpened"
|
||||
:collapse="properties.isCollapse"
|
||||
:collapse-transition="properties.transition"
|
||||
background-color="#252a2f"
|
||||
text-color="#d6d6d6"
|
||||
active-text-color="#ffd04b">
|
||||
<el-submenu index="1">
|
||||
<template slot="title">
|
||||
<i class="el-icon-setting"></i>
|
||||
<span>系统设置</span>
|
||||
</template>
|
||||
<el-menu-item index="1-1">用户管理</el-menu-item>
|
||||
<el-menu-item index="1-2">机构管理</el-menu-item>
|
||||
<el-menu-item index="1-3">角色管理</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-submenu index="2">
|
||||
<template slot="title">
|
||||
<i class="el-icon-time"></i>
|
||||
<span slot="title">日志管理</span>
|
||||
</template>
|
||||
<el-menu-item index="2-1">登录日志</el-menu-item>
|
||||
</el-submenu>
|
||||
</el-menu>
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
<div id="head">
|
||||
<div class="collapseSwitch" @click="collapseSwitch">
|
||||
<a :class="properties.isCollapse?'reversal':''"><i class="el-icon-s-grid"></i></a>
|
||||
</div>
|
||||
|
||||
<el-link :underline="false" @click="onHome" icon="el-icon-s-home">首页</el-link>
|
||||
|
||||
<div class="menu">
|
||||
<ul>
|
||||
<li>
|
||||
<el-link :underline="false" @click="onHome" icon="el-icon-message-solid"><span
|
||||
style="line-height: 20px;"><el-badge is-dot class="item">消息</el-badge></span></el-link>
|
||||
</li>
|
||||
<li>
|
||||
<el-dropdown>
|
||||
<el-link :underline="false" @click="onHome" icon="el-icon-user-solid">我的</el-link>
|
||||
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item>修改信息</el-dropdown-item>
|
||||
<el-dropdown-item>修改密码</el-dropdown-item>
|
||||
<el-dropdown-item>退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<el-link :underline="false" @click="onHome" icon="el-icon-warning">关于</el-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<el-tabs v-model="activeTabName" type="border-card" closable @tab-remove="removeTab">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in tabs"
|
||||
:key="item.name"
|
||||
:label="item.title"
|
||||
:name="item.name">
|
||||
<iframe :src="item.url" style="width: 100%;height: 100%;border: 0;"></iframe>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||
}
|
||||
|
||||
html, body, #index, #main, #content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#index {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#aside {
|
||||
background: #252a2f;
|
||||
}
|
||||
|
||||
#aside .el-menu {
|
||||
transition: all .5s;
|
||||
border-right: 0
|
||||
}
|
||||
|
||||
#aside .el-menu-item, .el-submenu__title {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
#main {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#head {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
overflow: hidden;
|
||||
background: #252a2f;
|
||||
}
|
||||
|
||||
#head .collapseSwitch {
|
||||
display: inline-block;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
border-left: 1px solid #424242;
|
||||
border-right: 1px solid #424242;
|
||||
}
|
||||
|
||||
#head .collapseSwitch a {
|
||||
display: inline-block;
|
||||
transition: all 1s;
|
||||
}
|
||||
|
||||
#head .collapseSwitch a.reversal {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
#head a {
|
||||
color: #d6d6d6;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#head a:hover {
|
||||
color: #409EFF;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#head .collapseSwitch:hover {
|
||||
background: #3b4146;
|
||||
}
|
||||
|
||||
#head .menu {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#head .menu ul {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#head .menu ul li {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#head .menu ul li a {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
margin: 0 10px;
|
||||
height: 40px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#head .menu ul li a:after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
background: #409EFF;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
position: absolute;
|
||||
bottom: 2px;
|
||||
left: 50%;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
#head .menu ul li a:hover:after {
|
||||
width: 100%;
|
||||
left: 0%;
|
||||
}
|
||||
|
||||
#content {
|
||||
height: calc(100% - 35px);
|
||||
}
|
||||
|
||||
#content > div {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#content > div > .el-tabs__content {
|
||||
padding: 0;
|
||||
height: calc(100% - 43px);
|
||||
}
|
||||
|
||||
#content .el-tabs__item {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
#content .el-tabs__nav {
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
#content > div > .el-tabs__content .el-tab-pane {
|
||||
height: 100%;
|
||||
background: #f0f2f5;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
window.index = new Vue({
|
||||
el: "#index",
|
||||
data: {
|
||||
tabs: [],//所有Tabs
|
||||
activeTabName: '',
|
||||
properties: {
|
||||
uniqueOpened: true,//是否保持一个子菜单展开
|
||||
isCollapse: false,//左侧菜单是否收缩
|
||||
transition:false,
|
||||
defaultActive:"1-1",
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onHome: function () {
|
||||
this.addTab({
|
||||
title: '首页',
|
||||
name: 'home',
|
||||
url: '${contextPath}/home.htm'
|
||||
})
|
||||
},
|
||||
collapseSwitch: function () {
|
||||
this.properties.isCollapse = !this.properties.isCollapse;
|
||||
},
|
||||
handleOpen: function () {
|
||||
|
||||
},
|
||||
handleClose: function () {
|
||||
|
||||
},
|
||||
handleSelect: function (index) {
|
||||
switch (index) {
|
||||
case "1-1":
|
||||
this.addTab({title: "用户管理", name: "usersManager", url: "about:blank"});
|
||||
break;
|
||||
case "1-2":
|
||||
this.addTab({title: "机构管理", name: "departmentsManager", url: "about:blank"});
|
||||
break;
|
||||
case "1-3":
|
||||
this.addTab({title: "角色管理", name: "rolesManager", url: "about:blank"});
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
addTab: function (tab) {
|
||||
//查找是否存在该tab
|
||||
var tempTabs = this.tabs.filter(function (tab_) {
|
||||
return tab_.name === tab.name;
|
||||
})
|
||||
//不存在则添加
|
||||
if (tempTabs.length <= 0) {
|
||||
this.tabs.push(tab)
|
||||
}
|
||||
this.activeTabName = tab.name;
|
||||
},
|
||||
removeTab: function (tabName) {
|
||||
var activeName = this.activeTabName;
|
||||
var tempTabs = this.tabs;
|
||||
if (activeName === tabName) {
|
||||
tempTabs.forEach(function (tab, index) {
|
||||
if (tab.name === tabName) {
|
||||
var nextTab = tempTabs[index + 1] || tempTabs[index - 1];
|
||||
if (nextTab) {
|
||||
activeName = nextTab.name;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
this.activeTabName = activeName;
|
||||
this.tabs = tempTabs.filter(function (tab) {
|
||||
return tab.name !== tabName
|
||||
})
|
||||
}
|
||||
},
|
||||
created: function () {
|
||||
},
|
||||
mounted: function () {
|
||||
this.onHome();//页面初始好后打开首页
|
||||
},
|
||||
watch: {}
|
||||
})
|
||||
</script>
|
||||
|
@ -0,0 +1,134 @@
|
||||
<div id="app" v-cloak>
|
||||
<div class="frame">
|
||||
<div class="login-box">
|
||||
<div class="login-title">系统登录</div>
|
||||
|
||||
<el-form :model="form" :rules="rules" ref="form" class="form">
|
||||
<el-form-item prop="name">
|
||||
<el-input placeholder="用户名" v-model="form.name">
|
||||
<template slot="prepend"><i class="icon iconfont el-icon-user"></i></template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="password">
|
||||
<el-input placeholder="密码" v-model="form.password" type="password">
|
||||
<template slot="prepend"><i class="icon iconfont el-icon-lock"></i></template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" style="width: 100%" :loading="isLogin" :disabled="isLogin"
|
||||
@click="submitForm('form')">登录
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<a class="tip">系统登录</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<style>
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
background: #001d3a;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.frame {
|
||||
width: 600px;
|
||||
height: 500px;
|
||||
background: #42424263;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 0 0 10px 0 #afafaf52;
|
||||
}
|
||||
|
||||
.login-box {
|
||||
display: inline-block;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.login-title {
|
||||
line-height: 50px;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
padding-left: 20px;
|
||||
font-size: 15px;
|
||||
height: 50px;
|
||||
color: #757575;
|
||||
}
|
||||
|
||||
.form {
|
||||
width: 300px;
|
||||
margin-top: 20px;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.form .el-input-group__prepend {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
padding: 5px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
color: #b7b7b7;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
var app = new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
form: {
|
||||
name: '',
|
||||
password: ''
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{required: true, message: '请输入用户名', trigger: 'blur'}
|
||||
],
|
||||
password: [
|
||||
{required: true, message: '请输入密码', trigger: 'change'}
|
||||
],
|
||||
},
|
||||
isLogin: false
|
||||
},
|
||||
mounted: function () {
|
||||
|
||||
},
|
||||
methods: {
|
||||
submitForm: function (formName) {
|
||||
this.$refs[formName].validate(function (valid) {
|
||||
if (valid) {
|
||||
this.isLogin = true;
|
||||
setTimeout(function(){
|
||||
nav.i("登录成功!", function () {
|
||||
location.href = "/index.htm"
|
||||
});
|
||||
},1000)
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
resetForm: function (formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
@ -0,0 +1,88 @@
|
||||
package com.example;
|
||||
|
||||
import com.example.frame.utils.*;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* UtilTest - - 测试用例
|
||||
*
|
||||
* @author wangbing
|
||||
* @version 0.0.1
|
||||
* @since 2017-01-01
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@Transactional
|
||||
public class UtilTest {
|
||||
|
||||
@Test
|
||||
public void testIDgenerator() {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
long l = IDgenerator.nextId();
|
||||
System.out.println(l);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAESUtil() {
|
||||
// 加密
|
||||
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));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBase64Util() {
|
||||
String s = Base64Util.encodeToString(("我搜搜").getBytes());
|
||||
System.out.println(s);
|
||||
|
||||
byte[] decode = Base64Util.decode(s);
|
||||
System.out.println(new String(decode));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMD5Util() {
|
||||
String encode = MD5Util.encode("123456");
|
||||
System.out.println(encode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessUtil() {
|
||||
ProcessUtil.execExe("D:\\example.exe");
|
||||
ProcessUtil.execBat("D:\\example.bat");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRSAUtil() {
|
||||
{//创建秘钥对
|
||||
RSAUtil.createKey();
|
||||
}
|
||||
|
||||
{//加解密
|
||||
|
||||
//加密
|
||||
String encrypt = RSAUtil.encrypt2Base64("我有一个苹果".getBytes());
|
||||
System.out.println(encrypt);
|
||||
|
||||
//解密
|
||||
String decrypt = RSAUtil.decrypt2String(encrypt);
|
||||
System.out.println(decrypt);
|
||||
}
|
||||
|
||||
|
||||
String sign = RSAUtil.sign2Base64("我有一个苹果".getBytes());
|
||||
System.out.println(sign);
|
||||
|
||||
boolean b = RSAUtil.doCheck("我有一个苹果".getBytes(), sign);
|
||||
System.out.println(b);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.example.config;
|
||||
|
||||
import com.example.frame.base.Token;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@Configuration
|
||||
public class TestConfig {
|
||||
|
||||
@Bean
|
||||
public Token getTestToken() {
|
||||
Token token = new Token();
|
||||
token.setId(0);
|
||||
token.setUserId(0);
|
||||
token.setUserName("system");
|
||||
return token;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
# 测试环境
|
||||
server.port=8080
|
||||
server.servlet.context-path=/
|
||||
spring.mvc.static-path-pattern=/static/**
|
||||
spring.resources.static-locations=classpath:static/
|
||||
spring.application.name=SpringBoot
|
||||
spring.main.banner-mode=CONSOLE
|
||||
spring.devtools.restart.enabled=true
|
||||
# 编码配置
|
||||
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.htm
|
||||
# 需要验证授权, 既访问时组装Token
|
||||
web.url.auth.included=/**
|
||||
# 不需要验证授权, 或该请求有自己的验证机制
|
||||
web.url.auth.excluded=/favicon.ico,/static/**,/api,/login.htm
|
||||
# 日志配置
|
||||
logging.path=D://
|
||||
logging.levels=DEBUG
|
||||
logging.config=classpath:logback-config.xml
|
||||
# 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
|
||||
# jackson 相关配置
|
||||
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
|
||||
spring.jackson.time-zone=GMT+8
|
||||
spring.jackson.default-property-inclusion=use_defaults
|
||||
spring.jackson.mapper.sort-properties-alphabetically=true
|
||||
spring.jackson.deserialization.fail-on-unknown-properties=false
|
||||
# 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=false
|
||||
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>
|
@ -0,0 +1,80 @@
|
||||
<?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>nginx-admin</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<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>
|
||||
<ehcache-version>1.1.0</ehcache-version>
|
||||
<dozer-version>5.5.1</dozer-version>
|
||||
<spring-cloud.version>Greenwich.RC2</spring-cloud.version>
|
||||
<wsqlite>1.0-SNAPSHOT</wsqlite>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- Spring 微服务 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<!-- sql分页插件 -->
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
<version>${pagehelper-version}</version>
|
||||
</dependency>
|
||||
<!-- spring-boot -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>${mybatis-version}</version>
|
||||
</dependency>
|
||||
<!-- mybatis 缓存框架 -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis.caches</groupId>
|
||||
<artifactId>mybatis-ehcache</artifactId>
|
||||
<version>${ehcache-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>
|
||||
<!-- sqlite封装模块 -->
|
||||
<dependency>
|
||||
<groupId>xyz.wbsite</groupId>
|
||||
<artifactId>wsqlite</artifactId>
|
||||
<version>${wsqlite}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</project>
|
@ -0,0 +1,24 @@
|
||||
<?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>xyz.wbsite</groupId>
|
||||
<artifactId>nginx-admin</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>xyz.wbsite</groupId>
|
||||
<artifactId>wsqlite</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.14.2.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,125 @@
|
||||
package xyz.wbsite.wsqlite;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.*;
|
||||
|
||||
/**
|
||||
* xyz.wbsite.wsqlite.Client
|
||||
*
|
||||
* @author wangbing
|
||||
*/
|
||||
public class Client {
|
||||
|
||||
Connection connection;
|
||||
Statement statement;
|
||||
ResultSet resultSet;
|
||||
String dbFilePath;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* @param dbFile 文件
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
public Client(File dbFile) throws ClassNotFoundException, SQLException {
|
||||
this.dbFilePath = dbFile.getAbsolutePath();
|
||||
if (!dbFile.exists()) {
|
||||
connection = getConnection();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行sql语句
|
||||
*
|
||||
* @param sql
|
||||
* @throws SQLException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public void execute(String sql) throws SQLException, ClassNotFoundException {
|
||||
try {
|
||||
getStatement().execute(sql);
|
||||
} finally {
|
||||
destroyed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行sql查询语句
|
||||
*
|
||||
* @param sql
|
||||
* @throws SQLException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public ResultSet executeQuery(String sql) throws SQLException, ClassNotFoundException {
|
||||
return getStatement().executeQuery(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行sql更新语句
|
||||
*
|
||||
* @param sqls
|
||||
* @throws SQLException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public int executeUpdate(String... sqls) throws SQLException, ClassNotFoundException {
|
||||
int count = 0;
|
||||
try {
|
||||
for (String sql : sqls) {
|
||||
count += getStatement().executeUpdate(sql);
|
||||
}
|
||||
} finally {
|
||||
destroyed();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库连接
|
||||
*
|
||||
* @return 数据库连接
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
Connection getConnection() throws ClassNotFoundException, SQLException {
|
||||
if (null == connection) {
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:" + dbFilePath);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库Statement对象
|
||||
*/
|
||||
Statement getStatement() throws SQLException, ClassNotFoundException {
|
||||
if (null == statement) {
|
||||
statement = getConnection().createStatement();
|
||||
}
|
||||
return statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库资源关闭和释放
|
||||
*/
|
||||
public void destroyed() {
|
||||
try {
|
||||
if (null != resultSet) {
|
||||
resultSet.close();
|
||||
resultSet = null;
|
||||
}
|
||||
|
||||
if (null != statement) {
|
||||
statement.close();
|
||||
statement = null;
|
||||
}
|
||||
if (null != connection) {
|
||||
connection.close();
|
||||
connection = null;
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue