diff --git a/demos/javaapp/pom.xml b/demos/javaapp/pom.xml index fa4af7c..4c87889 100644 --- a/demos/javaapp/pom.xml +++ b/demos/javaapp/pom.xml @@ -1,6 +1,6 @@ - + 4.0.0 io.github.dunwu JavaWebApp diff --git a/demos/javaapp/src/main/java/io/github/dunwu/Main.java b/demos/javaapp/src/main/java/io/github/dunwu/Main.java index b6fe78e..33ca08e 100644 --- a/demos/javaapp/src/main/java/io/github/dunwu/Main.java +++ b/demos/javaapp/src/main/java/io/github/dunwu/Main.java @@ -1,21 +1,26 @@ package io.github.dunwu; -import java.io.File; import org.apache.catalina.Server; import org.apache.catalina.startup.Catalina; import org.apache.catalina.startup.Tomcat; import org.apache.tomcat.util.digester.Digester; import org.apache.tomcat.util.scan.Constants; +import java.io.File; + public class Main { private static final String CONNECTOR_PORT = "8080"; // 以下设置轻易不要改动 private static final String RELATIVE_DEV_BASE_DIR = "src/main/resources/tomcat/"; + private static final String RELATIVE_BASE_DIR = "WEB-INF/classes/tomcat/"; + private static final String RELATIVE_DEV_DOCBASE_DIR = "src/main/webapp"; + private static final String RELATIVE_DOCBASE_DIR = ""; + private static final String CONTEXT_PATH = "/"; public static void main(String[] args) throws Exception { @@ -26,7 +31,8 @@ public class Main { if (!checkFile.exists()) { System.setProperty("catalina.base", getAbsolutePath() + RELATIVE_DEV_BASE_DIR); System.setProperty("tomcat.context.docBase", RELATIVE_DEV_DOCBASE_DIR); - } else { + } + else { System.setProperty("catalina.base", getAbsolutePath() + RELATIVE_BASE_DIR); System.setProperty("tomcat.context.docBase", RELATIVE_DOCBASE_DIR); } @@ -36,7 +42,7 @@ public class Main { } if (isBlank(System.getProperty("tomcat.server.shutdownPort"))) { System.setProperty("tomcat.server.shutdownPort", - String.valueOf(Integer.valueOf(System.getProperty("tomcat.connector.port")) + 10000)); + String.valueOf(Integer.valueOf(System.getProperty("tomcat.connector.port")) + 10000)); } if (isBlank(System.getProperty("tomcat.context.path"))) { System.setProperty("tomcat.context.path", CONTEXT_PATH); @@ -58,11 +64,11 @@ public class Main { private static String getAbsolutePath() { String path = null; - String folderPath = Main.class.getProtectionDomain().getCodeSource().getLocation() - .getPath(); + String folderPath = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath(); if (folderPath.indexOf("WEB-INF") > 0) { path = folderPath.substring(0, folderPath.indexOf("WEB-INF")); - } else if (folderPath.indexOf("target") > 0) { + } + else if (folderPath.indexOf("target") > 0) { path = folderPath.substring(0, folderPath.indexOf("target")); } return path; @@ -76,14 +82,8 @@ public class Main { } static class ExtendedTomcat extends Tomcat { - private static final String RELATIVE_SERVERXML_PATH = "/conf/server.xml"; - private class ExtendedCatalina extends Catalina { - @Override - public Digester createStartDigester() { - return super.createStartDigester(); - } - } + private static final String RELATIVE_SERVERXML_PATH = "/conf/server.xml"; @Override public Server getServer() { @@ -94,7 +94,7 @@ public class Main { System.setProperty("catalina.useNaming", "false"); ExtendedCatalina extendedCatalina = new ExtendedCatalina(); - //覆盖默认的skip和scan jar包配置 + // 覆盖默认的skip和scan jar包配置 System.setProperty(Constants.SKIP_JARS_PROPERTY, ""); System.setProperty(Constants.SCAN_JARS_PROPERTY, ""); @@ -102,17 +102,28 @@ public class Main { digester.push(extendedCatalina); try { server = ((ExtendedCatalina) digester - .parse(new File(System.getProperty("catalina.base") + RELATIVE_SERVERXML_PATH))).getServer(); + .parse(new File(System.getProperty("catalina.base") + RELATIVE_SERVERXML_PATH))).getServer(); // 设置catalina.base和catalna.home this.initBaseDir(); return server; - } catch (Exception e) { + } + catch (Exception e) { System.err.println("Error while parsing server.xml" + e.getMessage()); throw new RuntimeException("server未创建,请检查server.xml(路径:" + System.getProperty("catalina.base") - + RELATIVE_SERVERXML_PATH + ")配置是否正确"); + + RELATIVE_SERVERXML_PATH + ")配置是否正确"); } } - } -} + private class ExtendedCatalina extends Catalina { + + @Override + public Digester createStartDigester() { + return super.createStartDigester(); + } + + } + + } + +} diff --git a/demos/javaapp/src/main/java/io/github/dunwu/filter/CorsFilter.java b/demos/javaapp/src/main/java/io/github/dunwu/filter/CorsFilter.java index 46f8320..f4da586 100644 --- a/demos/javaapp/src/main/java/io/github/dunwu/filter/CorsFilter.java +++ b/demos/javaapp/src/main/java/io/github/dunwu/filter/CorsFilter.java @@ -1,103 +1,102 @@ package io.github.dunwu.filter; -import java.io.IOException; -import java.util.regex.Pattern; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.regex.Pattern; + /** * 跨域过滤器,根据正则进行匹配 */ public class CorsFilter implements Filter { - private static final Logger logger = LoggerFactory.getLogger(CorsFilter.class); - private String regex; - private String headerKey; - private String protocol = "http"; - private final String ORIGIN_KEY = "Origin"; + private static final Logger logger = LoggerFactory.getLogger(CorsFilter.class); + private final String ORIGIN_KEY = "Origin"; + private String regex; + private String headerKey; + private String protocol = "http"; - public void init(FilterConfig filterConfig) { - // 取配置参数 - regex = filterConfig.getInitParameter("regex"); - headerKey = filterConfig.getInitParameter("headerKey"); - String protocolVal = filterConfig.getInitParameter("protocol"); - if (StringUtils.isNotBlank(protocolVal)) { - if (StringUtils.equalsIgnoreCase("http", protocolVal) - || StringUtils.equalsIgnoreCase("https", protocolVal)) { - protocol = protocolVal.toLowerCase(); - } else { - logger.error("CorsFilter 配置参数 protocol 非法,仍使用默认值 http"); - } - } - } + public void init(FilterConfig filterConfig) { + // 取配置参数 + regex = filterConfig.getInitParameter("regex"); + headerKey = filterConfig.getInitParameter("headerKey"); + String protocolVal = filterConfig.getInitParameter("protocol"); + if (StringUtils.isNotBlank(protocolVal)) { + if (StringUtils.equalsIgnoreCase("http", protocolVal) + || StringUtils.equalsIgnoreCase("https", protocolVal)) { + protocol = protocolVal.toLowerCase(); + } + else { + logger.error("CorsFilter 配置参数 protocol 非法,仍使用默认值 http"); + } + } + } - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - HttpServletRequest httpRequest = (HttpServletRequest) request; - HttpServletResponse httpResponse = (HttpServletResponse) response; + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpServletResponse httpResponse = (HttpServletResponse) response; - if (StringUtils.isBlank(regex) || StringUtils.isBlank(headerKey)) { - throw new ServletException("读取跨域过滤器的配置参数失败"); - } + if (StringUtils.isBlank(regex) || StringUtils.isBlank(headerKey)) { + throw new ServletException("读取跨域过滤器的配置参数失败"); + } - // 读取请求地址的域 - String domain = httpRequest.getHeader(headerKey); - String origin = httpRequest.getHeader(ORIGIN_KEY); + // 读取请求地址的域 + String domain = httpRequest.getHeader(headerKey); + String origin = httpRequest.getHeader(ORIGIN_KEY); - if (StringUtils.isBlank(origin)) { - logger.debug("origin 为空, 跳过检查"); - chain.doFilter(httpRequest, httpResponse); - return; - } + if (StringUtils.isBlank(origin)) { + logger.debug("origin 为空, 跳过检查"); + chain.doFilter(httpRequest, httpResponse); + return; + } - if (StringUtils.isBlank(domain)) { - logger.debug("domain 为空, 跳过检查"); - chain.doFilter(httpRequest, httpResponse); - return; - } + if (StringUtils.isBlank(domain)) { + logger.debug("domain 为空, 跳过检查"); + chain.doFilter(httpRequest, httpResponse); + return; + } - if (origin.toLowerCase().contains(domain.toLowerCase())) { - // 判断请求方和应答方是否同为 http 或 https - // 如果相同,这里视为同源;否则,视为跨域 - if (origin.startsWith(protocol)) { - logger.debug("domain={}, origin={}, 二者协议相同,且域名同源,跳过检查", domain, origin); - chain.doFilter(httpRequest, httpResponse); - return; - } - } + if (origin.toLowerCase().contains(domain.toLowerCase())) { + // 判断请求方和应答方是否同为 http 或 https + // 如果相同,这里视为同源;否则,视为跨域 + if (origin.startsWith(protocol)) { + logger.debug("domain={}, origin={}, 二者协议相同,且域名同源,跳过检查", domain, origin); + chain.doFilter(httpRequest, httpResponse); + return; + } + } - Pattern pattern = Pattern.compile(regex); - if (!pattern.matcher(origin).matches()) { - logger.warn("客户端域 origin={} 不在跨域白名单中", origin); - httpResponse.sendError(403, "客户端域不在跨域白名单中"); - throw new ServletException("客户端域不在跨域白名单中"); - } + Pattern pattern = Pattern.compile(regex); + if (!pattern.matcher(origin).matches()) { + logger.warn("客户端域 origin={} 不在跨域白名单中", origin); + httpResponse.sendError(403, "客户端域不在跨域白名单中"); + throw new ServletException("客户端域不在跨域白名单中"); + } - logger.debug("对 origin={} 放开跨域限制", origin); - httpResponse.addHeader("Access-Control-Allow-Origin", origin); - httpResponse.addHeader("Access-Control-Allow-Credentials", "true"); - httpResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS, DELETE"); - httpResponse.addHeader("Access-Control-Allow-Headers", - "DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since," + - " Cache-Control, Content-Type, Content-Range, Range, X-CSRF-TOKEN"); - httpResponse.addHeader("Access-Control-Expose-Headers", - "DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since," + - " Cache-Control, Content-Type, Content-Range, Range"); - if (httpRequest.getMethod().equals("OPTIONS")) { - httpResponse.setStatus(HttpServletResponse.SC_OK); - return; - } - chain.doFilter(httpRequest, httpResponse); - } + logger.debug("对 origin={} 放开跨域限制", origin); + httpResponse.addHeader("Access-Control-Allow-Origin", origin); + httpResponse.addHeader("Access-Control-Allow-Credentials", "true"); + httpResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS, DELETE"); + httpResponse.addHeader("Access-Control-Allow-Headers", + "DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since," + + " Cache-Control, Content-Type, Content-Range, Range, X-CSRF-TOKEN"); + httpResponse.addHeader("Access-Control-Expose-Headers", + "DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since," + + " Cache-Control, Content-Type, Content-Range, Range"); + if (httpRequest.getMethod().equals("OPTIONS")) { + httpResponse.setStatus(HttpServletResponse.SC_OK); + return; + } + chain.doFilter(httpRequest, httpResponse); + } + + public void destroy() { + } - public void destroy() {} } diff --git a/demos/javaapp/src/main/java/io/github/dunwu/util/IOObjectMapper.java b/demos/javaapp/src/main/java/io/github/dunwu/util/IOObjectMapper.java index d275ccf..79704f2 100644 --- a/demos/javaapp/src/main/java/io/github/dunwu/util/IOObjectMapper.java +++ b/demos/javaapp/src/main/java/io/github/dunwu/util/IOObjectMapper.java @@ -5,8 +5,10 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; public class IOObjectMapper extends ObjectMapper { - public IOObjectMapper() { - this.setSerializationInclusion(Include.NON_EMPTY); - this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - } + + public IOObjectMapper() { + this.setSerializationInclusion(Include.NON_EMPTY); + this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + } diff --git a/demos/javaapp/src/main/java/io/github/dunwu/web/controller/ApiController.java b/demos/javaapp/src/main/java/io/github/dunwu/web/controller/ApiController.java index 86dde80..77228b0 100644 --- a/demos/javaapp/src/main/java/io/github/dunwu/web/controller/ApiController.java +++ b/demos/javaapp/src/main/java/io/github/dunwu/web/controller/ApiController.java @@ -4,12 +4,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import io.github.dunwu.web.dto.BaseResponseDTO; import io.github.dunwu.web.dto.MenuDTO; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; @@ -17,91 +11,101 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + /** * 配合前端请求的 API 接口 + * * @author zhangpeng0913 * @date 2017/8/23. */ @Controller public class ApiController { - @ResponseBody - @RequestMapping(value = "/menu", method = RequestMethod.GET) - public BaseResponseDTO getAll(HttpServletRequest request) throws JsonProcessingException { - String data = request.getParameter("data"); - BaseResponseDTO baseResponseDTO = new BaseResponseDTO(); - baseResponseDTO.setData(getAll()); - ObjectMapper om = new ObjectMapper(); - System.out.println("ResponseDTO: " + om.writeValueAsString(baseResponseDTO)); - return baseResponseDTO; - } + private static Set getAll() { + MenuDTO item0 = new MenuDTO("0", "首页", "home", "Item", "/pages/home"); - @ResponseBody - @RequestMapping(value = "/login") - public BaseResponseDTO login(@RequestBody Map map) throws IOException { - String username = map.get("username"); - String password = map.get("password"); - BaseResponseDTO> baseResponseDTO = new BaseResponseDTO(); - if (StringUtils.equals(username, "admin") && StringUtils.equals(password, "123456")) { - Map result = new HashMap(); - result.put("name", "admin"); - result.put("role", "ADMIN"); - result.put("uid", "1"); - baseResponseDTO.setData(result); - System.out.println(baseResponseDTO.toString()); - return baseResponseDTO; - } else { - baseResponseDTO.setCode(BaseResponseDTO.DEFAULT_RESPONSE_RESULT.SYSTEM_ERROR.value()); - baseResponseDTO.getMessages().add(BaseResponseDTO.DEFAULT_RESPONSE_RESULT.SYSTEM_ERROR.desc()); - return baseResponseDTO; - } - } + MenuDTO subMenu1 = new MenuDTO("1", "业务", "bars", "SubMenu", null); + MenuDTO item11 = new MenuDTO("11", "Mailbox", "mail", "Item", "/pages/mailbox"); + MenuDTO item12 = new MenuDTO("12", "用户列表", "user", "Item", "/pages/user"); + subMenu1.addChild(item11); + subMenu1.addChild(item12); - @ResponseBody - @RequestMapping(value = "/logout", method = RequestMethod.GET) - public BaseResponseDTO logout(HttpServletRequest request) { - BaseResponseDTO baseResponseDTO = new BaseResponseDTO(); - return baseResponseDTO; - } + MenuDTO subMenu2 = new MenuDTO("2", "Others", "coffee", "SubMenu", null); + MenuDTO itemGroup1 = new MenuDTO("21", "Group1", "windows-o", "ItemGroup", null); + MenuDTO item22 = new MenuDTO("22", "Group1-1", null, "Item", null); + MenuDTO divider = new MenuDTO("23", "Divider1", null, "Divider", null); + MenuDTO itemGroup2 = new MenuDTO("24", "Group2", "apple-o", "ItemGroup", null); + MenuDTO item25 = new MenuDTO("25", "Group2-1", null, "Item", null); + itemGroup1.addChild(item22); + itemGroup2.addChild(item25); + subMenu2.addChild(itemGroup1); + subMenu2.addChild(divider); + subMenu2.addChild(itemGroup2); - @ResponseBody - @RequestMapping(value = "/my", method = RequestMethod.GET) - public BaseResponseDTO my(HttpServletRequest request) { - Map map = new HashMap(); - map.put("name", "admin"); - map.put("role", "ADMIN"); - map.put("uid", "1"); - BaseResponseDTO baseResponseDTO = new BaseResponseDTO(); - baseResponseDTO.setData(map); - return baseResponseDTO; - } + Set menus = new TreeSet(); + menus.add(item0); + menus.add(subMenu1); + menus.add(subMenu2); - private static Set getAll() { - MenuDTO item0 = new MenuDTO("0", "首页", "home", "Item", "/pages/home"); + return menus; + } - MenuDTO subMenu1 = new MenuDTO("1", "业务", "bars", "SubMenu", null); - MenuDTO item11 = new MenuDTO("11", "Mailbox", "mail", "Item", "/pages/mailbox"); - MenuDTO item12 = new MenuDTO("12", "用户列表", "user", "Item", "/pages/user"); - subMenu1.addChild(item11); - subMenu1.addChild(item12); + @ResponseBody + @RequestMapping(value = "/menu", method = RequestMethod.GET) + public BaseResponseDTO getAll(HttpServletRequest request) throws JsonProcessingException { + String data = request.getParameter("data"); + BaseResponseDTO baseResponseDTO = new BaseResponseDTO(); + baseResponseDTO.setData(getAll()); + ObjectMapper om = new ObjectMapper(); + System.out.println("ResponseDTO: " + om.writeValueAsString(baseResponseDTO)); + return baseResponseDTO; + } - MenuDTO subMenu2 = new MenuDTO("2", "Others", "coffee", "SubMenu", null); - MenuDTO itemGroup1 = new MenuDTO("21", "Group1", "windows-o", "ItemGroup", null); - MenuDTO item22 = new MenuDTO("22", "Group1-1", null, "Item", null); - MenuDTO divider = new MenuDTO("23", "Divider1", null, "Divider", null); - MenuDTO itemGroup2 = new MenuDTO("24", "Group2", "apple-o", "ItemGroup", null); - MenuDTO item25 = new MenuDTO("25", "Group2-1", null, "Item", null); - itemGroup1.addChild(item22); - itemGroup2.addChild(item25); - subMenu2.addChild(itemGroup1); - subMenu2.addChild(divider); - subMenu2.addChild(itemGroup2); + @ResponseBody + @RequestMapping(value = "/login") + public BaseResponseDTO login(@RequestBody Map map) throws IOException { + String username = map.get("username"); + String password = map.get("password"); + BaseResponseDTO> baseResponseDTO = new BaseResponseDTO(); + if (StringUtils.equals(username, "admin") && StringUtils.equals(password, "123456")) { + Map result = new HashMap(); + result.put("name", "admin"); + result.put("role", "ADMIN"); + result.put("uid", "1"); + baseResponseDTO.setData(result); + System.out.println(baseResponseDTO.toString()); + return baseResponseDTO; + } + else { + baseResponseDTO.setCode(BaseResponseDTO.DEFAULT_RESPONSE_RESULT.SYSTEM_ERROR.value()); + baseResponseDTO.getMessages().add(BaseResponseDTO.DEFAULT_RESPONSE_RESULT.SYSTEM_ERROR.desc()); + return baseResponseDTO; + } + } - Set menus = new TreeSet(); - menus.add(item0); - menus.add(subMenu1); - menus.add(subMenu2); + @ResponseBody + @RequestMapping(value = "/logout", method = RequestMethod.GET) + public BaseResponseDTO logout(HttpServletRequest request) { + BaseResponseDTO baseResponseDTO = new BaseResponseDTO(); + return baseResponseDTO; + } + + @ResponseBody + @RequestMapping(value = "/my", method = RequestMethod.GET) + public BaseResponseDTO my(HttpServletRequest request) { + Map map = new HashMap(); + map.put("name", "admin"); + map.put("role", "ADMIN"); + map.put("uid", "1"); + BaseResponseDTO baseResponseDTO = new BaseResponseDTO(); + baseResponseDTO.setData(map); + return baseResponseDTO; + } - return menus; - } } diff --git a/demos/javaapp/src/main/java/io/github/dunwu/web/controller/HelloController.java b/demos/javaapp/src/main/java/io/github/dunwu/web/controller/HelloController.java index c08dfd8..794b876 100644 --- a/demos/javaapp/src/main/java/io/github/dunwu/web/controller/HelloController.java +++ b/demos/javaapp/src/main/java/io/github/dunwu/web/controller/HelloController.java @@ -8,15 +8,19 @@ import org.springframework.web.servlet.ModelAndView; /** * spring mvc 的第一个程序 + * * @author Zhang Peng * @since 2016.07.29 */ @Controller @RequestMapping(value = "/hello") public class HelloController { + /** - *

在本例中,Spring将会将数据传给 hello.jsp - *

访问形式:http://localhost:8080/hello?name=张三 + *

+ * 在本例中,Spring将会将数据传给 hello.jsp + *

+ * 访问形式:http://localhost:8080/hello?name=张三 */ @RequestMapping(value = "/name", method = RequestMethod.GET) public ModelAndView hello(@RequestParam("name") String name) { @@ -25,4 +29,5 @@ public class HelloController { mav.setViewName("hello"); return mav; } + } diff --git a/demos/javaapp/src/main/java/io/github/dunwu/web/controller/IndexController.java b/demos/javaapp/src/main/java/io/github/dunwu/web/controller/IndexController.java index c473e77..db118bb 100644 --- a/demos/javaapp/src/main/java/io/github/dunwu/web/controller/IndexController.java +++ b/demos/javaapp/src/main/java/io/github/dunwu/web/controller/IndexController.java @@ -14,9 +14,12 @@ import org.springframework.web.servlet.ModelAndView; */ @Controller public class IndexController { + /** - *

返回 ModelAndView 对象到视图层。在本例中,视图解析器解析视图名为 index,会自动关联到 index.jsp。 - *

访问形式:http://localhost:8080/ + *

+ * 返回 ModelAndView 对象到视图层。在本例中,视图解析器解析视图名为 index,会自动关联到 index.jsp。 + *

+ * 访问形式:http://localhost:8080/ */ @RequestMapping(value = "/", method = RequestMethod.GET) public ModelAndView index() { @@ -24,4 +27,5 @@ public class IndexController { mav.setViewName("index"); return mav; } + } diff --git a/demos/javaapp/src/main/java/io/github/dunwu/web/dto/BaseResponseDTO.java b/demos/javaapp/src/main/java/io/github/dunwu/web/dto/BaseResponseDTO.java index cdff39f..cbb90f5 100644 --- a/demos/javaapp/src/main/java/io/github/dunwu/web/dto/BaseResponseDTO.java +++ b/demos/javaapp/src/main/java/io/github/dunwu/web/dto/BaseResponseDTO.java @@ -6,82 +6,80 @@ import java.util.List; public class BaseResponseDTO { - private Integer code = DEFAULT_RESPONSE_RESULT.SUCCESS.value(); + private final List messages = new ArrayList<>(); + private Integer code = DEFAULT_RESPONSE_RESULT.SUCCESS.value(); + private T data; - private final List messages = new ArrayList<>(); + public BaseResponseDTO() { + } - private T data; + public BaseResponseDTO(T dto) { + this.data = dto; + } - public BaseResponseDTO() {} + public Integer getCode() { + return code; + } - public BaseResponseDTO(T dto) { - this.data = dto; - } + public void setCode(Integer code) { + this.code = code; + } - public Integer getCode() { - return code; - } + public void addError(String error) { + this.messages.add(error); + } - public void setCode(Integer code) { - this.code = code; - } + public void addErrors(String[] errors) { + this.addErrors(Arrays.asList(errors)); + } - public void addError(String error) { - this.messages.add(error); - } + public void addErrors(List errorList) { + this.messages.addAll(errorList); + } - public void addErrors(String[] errors) { - this.addErrors(Arrays.asList(errors)); - } + public void removeError(String error) { + this.messages.remove(error); + } - public void addErrors(List errorList) { - this.messages.addAll(errorList); - } + public List getMessages() { + return messages; + } - public void removeError(String error) { - this.messages.remove(error); - } + public T getData() { + return data; + } - public List getMessages() { - return messages; - } + public void setData(T data) { + this.data = data; + } - public T getData() { - return data; - } + public enum DEFAULT_RESPONSE_RESULT { - public void setData(T data) { - this.data = data; - } + SUCCESS(0, "[]"), // 成功 + AUTHEN_FAIL(-1, "认证失败"), // 认证失败 + AUTHOR_FAIL(-2, "权限不足"), // 授权不足 + PARAM_CHECK_FAIL(-3, ""), // 参数校验失败,错误信息交由业务逻辑处理 + RESOURCE_NOT_EXIST(-4, "请求资源不存在"), // 请求资源不存在 + SYSTEM_ERROR(-5, "系统错误"), DATA_MALFORMAT(-6, "请求参数数据格式不正确"), REQMETHOD_ERROR(-7, "请求方法不正确"), TYPE_MISMATCH(-8, + "请求参数类型不匹配"), MISS_REQUEST_PARAM(-9, "请求参数缺失"); - public enum DEFAULT_RESPONSE_RESULT { - SUCCESS(0, "[]"), // 成功 - AUTHEN_FAIL(-1, "认证失败"), // 认证失败 - AUTHOR_FAIL(-2, "权限不足"), // 授权不足 - PARAM_CHECK_FAIL(-3, ""), // 参数校验失败,错误信息交由业务逻辑处理 - RESOURCE_NOT_EXIST(-4, "请求资源不存在"), // 请求资源不存在 - SYSTEM_ERROR(-5, "系统错误"), - DATA_MALFORMAT(-6, "请求参数数据格式不正确"), - REQMETHOD_ERROR(-7, "请求方法不正确"), - TYPE_MISMATCH(-8, "请求参数类型不匹配"), - MISS_REQUEST_PARAM(-9, "请求参数缺失"); + private final Integer value; - private final Integer value; + private final String desc; - private final String desc; + DEFAULT_RESPONSE_RESULT(int value, String desc) { + this.value = value; + this.desc = desc; + } - DEFAULT_RESPONSE_RESULT(int value, String desc) { - this.value = value; - this.desc = desc; - } + public int value() { + return value; + } - public int value() { - return value; - } + public String desc() { + return desc; + } - public String desc() { - return desc; - } - } + } } diff --git a/demos/javaapp/src/main/java/io/github/dunwu/web/dto/MenuDTO.java b/demos/javaapp/src/main/java/io/github/dunwu/web/dto/MenuDTO.java index 1abec79..4c53aed 100644 --- a/demos/javaapp/src/main/java/io/github/dunwu/web/dto/MenuDTO.java +++ b/demos/javaapp/src/main/java/io/github/dunwu/web/dto/MenuDTO.java @@ -1,122 +1,120 @@ package io.github.dunwu.web.dto; -import java.util.Arrays; -import java.util.Set; -import java.util.TreeSet; import org.apache.commons.lang3.builder.CompareToBuilder; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import java.util.Arrays; +import java.util.Set; +import java.util.TreeSet; + public class MenuDTO implements Cloneable, Comparable { - private String key; + private final Set children = new TreeSet(); + private String key; + private String title; + private String icon; + private String type; + private String url; - private String title; + public MenuDTO() { + } - private String icon; + public MenuDTO(String key, String title, String icon, String type, String url) { + this.key = key; + this.title = title; + this.icon = icon; + this.type = type; + this.url = url; + } - private String type; + public MenuDTO clone() throws CloneNotSupportedException { + super.clone(); + MenuDTO menuDTO = new MenuDTO(); + menuDTO.setType(type); + menuDTO.setKey(key); + menuDTO.setTitle(title); + menuDTO.setIcon(icon); + menuDTO.setUrl(url); + menuDTO.setUrl(url); + return menuDTO; + } - private String url; + public String getKey() { + return key; + } - private final Set children = new TreeSet(); + public void setKey(String key) { + this.key = key; + } - public MenuDTO() {} + public String getTitle() { + return title; + } - public MenuDTO(String key, String title, String icon, String type, String url) { - this.key = key; - this.title = title; - this.icon = icon; - this.type = type; - this.url = url; - } + public void setTitle(String title) { + this.title = title; + } - public MenuDTO clone() throws CloneNotSupportedException { - super.clone(); - MenuDTO menuDTO = new MenuDTO(); - menuDTO.setType(type); - menuDTO.setKey(key); - menuDTO.setTitle(title); - menuDTO.setIcon(icon); - menuDTO.setUrl(url); - menuDTO.setUrl(url); - return menuDTO; - } + public String getIcon() { + return icon; + } - public String getKey() { - return key; - } + public void setIcon(String icon) { + this.icon = icon; + } - public void setKey(String key) { - this.key = key; - } + public String getType() { + return type; + } - public String getTitle() { - return title; - } + public void setType(String type) { + this.type = type; + } - public void setTitle(String title) { - this.title = title; - } + public String getUrl() { + return url; + } - public String getIcon() { - return icon; - } + public void setUrl(String url) { + this.url = url; + } - public void setIcon(String icon) { - this.icon = icon; - } + public Set getChildren() { + return children; + } - public String getType() { - return type; - } + public void addChild(MenuDTO child) { + this.children.add(child); + } - public void setType(String type) { - this.type = type; - } + public void addChildren(Set children) { + this.children.addAll(children); + } - public String getUrl() { - return url; - } + public void addChildren(MenuDTO[] children) { + this.children.addAll(Arrays.asList(children)); + } - public void setUrl(String url) { - this.url = url; - } + @Override + public boolean equals(Object obj) { + boolean equals = false; + if (obj instanceof MenuDTO) { + MenuDTO menuDTO = (MenuDTO) obj; + equals = (new EqualsBuilder().append(url, menuDTO.getUrl())).isEquals(); + } + return equals; + } - public Set getChildren() { - return children; - } + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37).append(url).toHashCode(); + } - public void addChild(MenuDTO child) { - this.children.add(child); - } + @Override + public int compareTo(MenuDTO otherMenuDTO) { + return new CompareToBuilder().append(key, otherMenuDTO.getKey()).append(url, otherMenuDTO.getUrl()) + .toComparison(); + } - public void addChildren(Set children) { - this.children.addAll(children); - } - - public void addChildren(MenuDTO[] children) { - this.children.addAll(Arrays.asList(children)); - } - - @Override - public boolean equals(Object obj) { - boolean equals = false; - if (obj instanceof MenuDTO) { - MenuDTO menuDTO = (MenuDTO) obj; - equals = (new EqualsBuilder().append(url, menuDTO.getUrl())).isEquals(); - } - return equals; - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37).append(url).toHashCode(); - } - - @Override - public int compareTo(MenuDTO otherMenuDTO) { - return new CompareToBuilder().append(key, otherMenuDTO.getKey()).append(url, otherMenuDTO.getUrl()) - .toComparison(); - } } diff --git a/demos/javaapp/src/main/resources/spring/spring-servlet.xml b/demos/javaapp/src/main/resources/spring/spring-servlet.xml index 34495cc..025c1f2 100644 --- a/demos/javaapp/src/main/resources/spring/spring-servlet.xml +++ b/demos/javaapp/src/main/resources/spring/spring-servlet.xml @@ -1,9 +1,9 @@ - - + class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"> + - + diff --git a/demos/javaapp/src/main/resources/tomcat/conf/server.xml b/demos/javaapp/src/main/resources/tomcat/conf/server.xml index 1cf33aa..c1f05e7 100644 --- a/demos/javaapp/src/main/resources/tomcat/conf/server.xml +++ b/demos/javaapp/src/main/resources/tomcat/conf/server.xml @@ -6,24 +6,24 @@ + maxThreads="300" minSpareThreads="25"/> + executor="tomcatThreadPool" + processorCache="300" bindOnInit="false"/> + autoDeploy="false" + deployOnStartup="false" failCtxIfServletStartFails="true"> + logEffectiveWebXml="false" + privileged="false" + swallowOutput="false" workDir="${catalina.base}/work"> + defaultPluggabilityScan="true" tldSkip="*.jar" + tldScan="" defaultTldScan="true"/> diff --git a/demos/javaapp/src/main/resources/tomcat/conf/web.xml b/demos/javaapp/src/main/resources/tomcat/conf/web.xml index aa7713a..b9a6de4 100644 --- a/demos/javaapp/src/main/resources/tomcat/conf/web.xml +++ b/demos/javaapp/src/main/resources/tomcat/conf/web.xml @@ -15,11 +15,11 @@ See the License for the specific language governing permissions and limitations under the License. --> - + version="3.1"> diff --git a/demos/javaapp/src/main/webapp/WEB-INF/web.xml b/demos/javaapp/src/main/webapp/WEB-INF/web.xml index eb85c98..f2a86ac 100644 --- a/demos/javaapp/src/main/webapp/WEB-INF/web.xml +++ b/demos/javaapp/src/main/webapp/WEB-INF/web.xml @@ -1,6 +1,6 @@ - + spring-embed-tomcat-demo-helloworld diff --git a/demos/javaapp/src/main/webapp/views/jsp/hello.jsp b/demos/javaapp/src/main/webapp/views/jsp/hello.jsp index 6341bd0..774fc94 100644 --- a/demos/javaapp/src/main/webapp/views/jsp/hello.jsp +++ b/demos/javaapp/src/main/webapp/views/jsp/hello.jsp @@ -1,14 +1,13 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <% - String path = request.getContextPath(); - String basePath = - request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; + String path = request.getContextPath(); + String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> - HelloController + HelloController

${message}

diff --git a/demos/javaapp/src/main/webapp/views/jsp/index.jsp b/demos/javaapp/src/main/webapp/views/jsp/index.jsp index b44ae62..6fd2308 100644 --- a/demos/javaapp/src/main/webapp/views/jsp/index.jsp +++ b/demos/javaapp/src/main/webapp/views/jsp/index.jsp @@ -1,9 +1,9 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <% - String domain = request.getScheme() + "://" + request.getServerName() + request.getContextPath(); - String host = request.getRemoteHost(); -// int port = request.getServerPort(); - Integer port = Integer.valueOf(System.getProperty("tomcat.connector.port")); + String domain = request.getScheme() + "://" + request.getServerName() + request.getContextPath(); + String host = request.getRemoteHost(); + // int port = request.getServerPort(); + Integer port = Integer.valueOf(System.getProperty("tomcat.connector.port")); %> @@ -11,16 +11,16 @@ - spring-embed-tomcat-demo + spring-embed-tomcat-demo

spring-embed-tomcat-demo

<%out.print("当前服务器信息:");%>

    -
  • <%out.print("domain:" + domain);%>
  • -
  • <%out.print("host:" + host);%>
  • -
  • <%out.print("port:" + port);%>
  • +
  • <%out.print("domain:" + domain);%>
  • +
  • <%out.print("host:" + host);%>
  • +
  • <%out.print("port:" + port);%>
diff --git a/demos/nginx-1.14.0/html/50x.html b/demos/nginx-1.14.0/html/50x.html index f60f5e7..1afb814 100644 --- a/demos/nginx-1.14.0/html/50x.html +++ b/demos/nginx-1.14.0/html/50x.html @@ -1,21 +1,21 @@ -Error - +

An error occurred.

Sorry, the page you are looking for is currently unavailable.
-Please try again later.

+ Please try again later.

If you are the system administrator of this resource then you should check -the error log for details.

+ the error log for details.

Faithfully yours, nginx.

diff --git a/demos/nginx-1.14.0/html/index.html b/demos/nginx-1.14.0/html/index.html index 2ca3b95..3e95532 100644 --- a/demos/nginx-1.14.0/html/index.html +++ b/demos/nginx-1.14.0/html/index.html @@ -1,24 +1,24 @@ -Welcome to nginx! - +

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and -working. Further configuration is required.

+ working. Further configuration is required.

For online documentation and support please refer to -nginx.org.
-Commercial support is available at -nginx.com.

+ nginx.org.
+ Commercial support is available at + nginx.com.

Thank you for using nginx.

diff --git a/demos/reactadmin/public/index.html b/demos/reactadmin/public/index.html index 323182f..91dcfc3 100644 --- a/demos/reactadmin/public/index.html +++ b/demos/reactadmin/public/index.html @@ -1,41 +1,41 @@ - - - - - - - - + + - React App - - - -
- + React App + + + +
+ - + To begin the development, run `npm start` or `yarn start`. + To create a production bundle, use `npm run build` or `yarn build`. +--> + diff --git a/demos/reactadmin/src/App.css b/demos/reactadmin/src/App.css index 92f956e..b14705a 100644 --- a/demos/reactadmin/src/App.css +++ b/demos/reactadmin/src/App.css @@ -8,7 +8,7 @@ } .App-header { - background-color: #282c34; + background-color: #282C34; min-height: 100vh; display: flex; flex-direction: column; @@ -19,7 +19,7 @@ } .App-link { - color: #61dafb; + color: #61DAFB; } @keyframes App-logo-spin { diff --git a/demos/reactadmin/src/App.js b/demos/reactadmin/src/App.js index 7e261ca..208db6b 100644 --- a/demos/reactadmin/src/App.js +++ b/demos/reactadmin/src/App.js @@ -1,28 +1,35 @@ -import React, { Component } from 'react'; -import logo from './logo.svg'; -import './App.css'; +import React, { Component } from 'react' +import logo from './logo.svg' +import './App.css' class App extends Component { render() { return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
- ); + < div + className = 'App' > + < header + className = 'App-header' > + < img + src = { logo } + className = 'App-logo' + alt = 'logo' / > + < p > + Edit < code > src / App.js < /code> and save to reload. + < /p> + < a + className = 'App-link' + href = 'https://reactjs.org' + target = '_blank' + rel = 'noopener noreferrer' + > + Learn + React + < /a> + < /header> + < /div> + ) + } } -export default App; +export default App diff --git a/demos/reactadmin/src/App.test.js b/demos/reactadmin/src/App.test.js index a754b20..dc3b5e7 100644 --- a/demos/reactadmin/src/App.test.js +++ b/demos/reactadmin/src/App.test.js @@ -1,9 +1,10 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './App'; +import ReactDOM from 'react-dom' +import App from './App' it('renders without crashing', () => { - const div = document.createElement('div'); - ReactDOM.render(, div); - ReactDOM.unmountComponentAtNode(div); -}); + const div = document.createElement('div') + ReactDOM.render( < App / >, div +) + + ReactDOM.unmountComponentAtNode(div) +}) diff --git a/demos/reactadmin/src/index.css b/demos/reactadmin/src/index.css index cee5f34..5b6b166 100644 --- a/demos/reactadmin/src/index.css +++ b/demos/reactadmin/src/index.css @@ -2,13 +2,13 @@ body { margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; + "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } code { font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; + monospace; } diff --git a/demos/reactadmin/src/index.js b/demos/reactadmin/src/index.js index 0c5e75d..f5d1d13 100644 --- a/demos/reactadmin/src/index.js +++ b/demos/reactadmin/src/index.js @@ -1,12 +1,13 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import './index.css'; -import App from './App'; -import * as serviceWorker from './serviceWorker'; +import ReactDOM from 'react-dom' +import './index.css' +import App from './App' +import * as serviceWorker from './serviceWorker' + +ReactDOM.render( < App / >, document.getElementById('root') +) -ReactDOM.render(, document.getElementById('root')); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: http://bit.ly/CRA-PWA -serviceWorker.unregister(); +serviceWorker.unregister() diff --git a/demos/reactadmin/src/logo.svg b/demos/reactadmin/src/logo.svg index 6b60c10..6d75536 100644 --- a/demos/reactadmin/src/logo.svg +++ b/demos/reactadmin/src/logo.svg @@ -1,7 +1,8 @@ - - - - - + + + + + diff --git a/demos/reactadmin/src/serviceWorker.js b/demos/reactadmin/src/serviceWorker.js index 2283ff9..efcb29e 100644 --- a/demos/reactadmin/src/serviceWorker.js +++ b/demos/reactadmin/src/serviceWorker.js @@ -12,124 +12,124 @@ const isLocalhost = Boolean( window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.1/8 is considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) -); + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.1/8 is considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) +) export function register(config) { if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); + const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href) if (publicUrl.origin !== window.location.origin) { // Our service worker won't work if PUBLIC_URL is on a different origin // from what our page is served on. This might happen if a CDN is used to // serve assets; see https://github.com/facebook/create-react-app/issues/2374 - return; + return } window.addEventListener('load', () => { - const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js` if (isLocalhost) { // This is running on localhost. Let's check if a service worker still exists or not. - checkValidServiceWorker(swUrl, config); + checkValidServiceWorker(swUrl, config) // Add some additional logging to localhost, pointing developers to the // service worker/PWA documentation. navigator.serviceWorker.ready.then(() => { console.log( 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit http://bit.ly/CRA-PWA' - ); - }); + 'worker. To learn more, visit http://bit.ly/CRA-PWA' + ) + }) } else { // Is not localhost. Just register service worker - registerValidSW(swUrl, config); + registerValidSW(swUrl, config) } - }); + }) } } function registerValidSW(swUrl, config) { navigator.serviceWorker - .register(swUrl) - .then(registration => { - registration.onupdatefound = () => { - const installingWorker = registration.installing; - if (installingWorker == null) { - return; - } - installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { - if (navigator.serviceWorker.controller) { - // At this point, the updated precached content has been fetched, - // but the previous service worker will still serve the older - // content until all client tabs are closed. - console.log( - 'New content is available and will be used when all ' + - 'tabs for this page are closed. See http://bit.ly/CRA-PWA.' - ); + .register(swUrl) + .then(registration => { + registration.onupdatefound = () => { + const installingWorker = registration.installing + if (installingWorker == null) { + return + } + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + console.log( + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See http://bit.ly/CRA-PWA.' + ) - // Execute callback - if (config && config.onUpdate) { - config.onUpdate(registration); - } - } else { - // At this point, everything has been precached. - // It's the perfect time to display a - // "Content is cached for offline use." message. - console.log('Content is cached for offline use.'); + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration) + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.') - // Execute callback - if (config && config.onSuccess) { - config.onSuccess(registration); - } + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration) } } - }; - }; - }) - .catch(error => { - console.error('Error during service worker registration:', error); - }); + } + } + } + }) + .catch(error => { + console.error('Error during service worker registration:', error) + }) } function checkValidServiceWorker(swUrl, config) { // Check if the service worker can be found. If it can't reload the page. fetch(swUrl) - .then(response => { - // Ensure service worker exists, and that we really are getting a JS file. - const contentType = response.headers.get('content-type'); - if ( - response.status === 404 || - (contentType != null && contentType.indexOf('javascript') === -1) - ) { - // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then(registration => { - registration.unregister().then(() => { - window.location.reload(); - }); - }); - } else { - // Service worker found. Proceed as normal. - registerValidSW(swUrl, config); - } - }) - .catch(() => { - console.log( - 'No internet connection found. App is running in offline mode.' - ); - }); + .then(response => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get('content-type') + if ( + response.status === 404 || + (contentType != null && contentType.indexOf('javascript') === -1) + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then(registration => { + registration.unregister().then(() => { + window.location.reload() + }) + }) + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config) + } + }) + .catch(() => { + console.log( + 'No internet connection found. App is running in offline mode.' + ) + }) } export function unregister() { if ('serviceWorker' in navigator) { navigator.serviceWorker.ready.then(registration => { - registration.unregister(); - }); + registration.unregister() + }) } } diff --git a/demos/reactapp/config/app.config.js b/demos/reactapp/config/app.config.js index 17a2492..9210821 100644 --- a/demos/reactapp/config/app.config.js +++ b/demos/reactapp/config/app.config.js @@ -20,6 +20,6 @@ module.exports = { /** * 服务器的host */ - baseURL: '/api', + baseURL: '/api' } -}; +} diff --git a/demos/reactapp/config/webpack.config.base.js b/demos/reactapp/config/webpack.config.base.js index a80acf7..1f99e03 100644 --- a/demos/reactapp/config/webpack.config.base.js +++ b/demos/reactapp/config/webpack.config.base.js @@ -1,9 +1,9 @@ /** * Created by Zhang Peng on 2017/6/14. */ -const path = require('path'); -const webpack = require('webpack'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); +const path = require('path') +const webpack = require('webpack') +const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { @@ -20,16 +20,16 @@ module.exports = { output: { // 所有输出文件的目标路径 // 必须是绝对路径(使用 Node.js 的 path 模块) - path: path.resolve(__dirname, "../dist"), + path: path.resolve(__dirname, '../dist'), // 「入口分块(entry chunk)」的文件名模板(出口分块?) // filename: "bundle.min.js", // filename: "[name].js", // 用于多个入口点(entry point)(出口点?) // filename: "[chunkhash].js", // 用于长效缓存 - filename: "[name].[hash:8].js", + filename: '[name].[hash:8].js', // 「source map 位置」的文件名模板 - sourceMapFilename: "[name].map", + sourceMapFilename: '[name].map' }, // 关于模块配置 @@ -47,13 +47,13 @@ module.exports = { { // 语义解释器,将 js/jsx 文件中的 es2015/react 语法自动转为浏览器可识别的 Javascript 语法 test: /\.jsx?$/, - include: path.resolve(__dirname, "../src"), + include: path.resolve(__dirname, '../src'), exclude: /node_modules/, // 应该应用的 loader,它相对上下文解析 // 为了更清晰,`-loader` 后缀在 webpack 2 中不再是可选的 // 查看 webpack 1 升级指南。 - loader: "babel-loader", + loader: 'babel-loader' }, { @@ -87,7 +87,7 @@ module.exports = { extensions: ['.js', '.jsx', '.json'], alias: { - "@": path.resolve(__dirname, "../src") + '@': path.resolve(__dirname, '../src') } }, @@ -99,15 +99,15 @@ module.exports = { * 用于简化 HTML 文件(index.html)的创建,提供访问 bundle 的服务 */ new HtmlWebpackPlugin({ - title: "reactapp", - template: "public/index.html", - favicon: "public/favicon.ico", + title: 'reactapp', + template: 'public/index.html', + favicon: 'public/favicon.ico' }), // 将多个入口起点之间共享的公共模块,生成为一些 chunk,并且分离到单独的 bundle 中 new webpack.optimize.CommonsChunkPlugin({ - name: "vendor" // 指定公共 bundle 的名字 - }), - ], -}; + name: 'vendor' // 指定公共 bundle 的名字 + }) + ] +} diff --git a/demos/reactapp/config/webpack.config.dev.js b/demos/reactapp/config/webpack.config.dev.js index 6e97593..74e7705 100644 --- a/demos/reactapp/config/webpack.config.dev.js +++ b/demos/reactapp/config/webpack.config.dev.js @@ -1,11 +1,11 @@ /** * Created by Zhang Peng on 2017/6/14. */ -const path = require('path'); -const webpack = require('webpack'); -const webpackMerge = require('webpack-merge'); -const OpenBrowserPlugin = require('open-browser-webpack-plugin'); -const baseWebpackConfig = require('./webpack.config.base'); +const path = require('path') +const webpack = require('webpack') +const webpackMerge = require('webpack-merge') +const OpenBrowserPlugin = require('open-browser-webpack-plugin') +const baseWebpackConfig = require('./webpack.config.base') module.exports = webpackMerge(baseWebpackConfig, { // 这里应用程序开始执行 @@ -14,7 +14,7 @@ module.exports = webpackMerge(baseWebpackConfig, { entry: { main: [ // App 入口 - path.resolve(__dirname, "../src/index"), + path.resolve(__dirname, '../src/index'), // 开启 React 代码的模块热替换(HMR) 'react-hot-loader/patch', @@ -25,13 +25,13 @@ module.exports = webpackMerge(baseWebpackConfig, { // 为热替换(HMR)打包好代码 // only- 意味着只有成功更新运行代码才会执行热替换(HMR) - 'webpack/hot/only-dev-server', - ], + 'webpack/hot/only-dev-server' + ] }, output: { // 对于热替换(HMR)是必须的,让 webpack 知道在哪里载入热更新的模块(chunk) - publicPath: "/", + publicPath: '/' }, // 关于模块配置 @@ -48,7 +48,7 @@ module.exports = webpackMerge(baseWebpackConfig, { limit: 10000, name: 'static/images/[name].[hash:8].[ext]' } - }, + } ] }, @@ -68,8 +68,8 @@ module.exports = webpackMerge(baseWebpackConfig, { // 自动打开浏览器 new OpenBrowserPlugin({ - url: "http://localhost:9000" - }), + url: 'http://localhost:9000' + }) ], // 通过在浏览器调试工具(browser devtools)中添加元信息(meta info)增强调试 @@ -78,16 +78,16 @@ module.exports = webpackMerge(baseWebpackConfig, { // devtool: "eval-source-map", // 将 SourceMap 嵌入到每个模块中 // devtool: "hidden-source-map", // SourceMap 不在源文件中引用 // devtool: "cheap-source-map", // 没有模块映射(module mappings)的 SourceMap 低级变体(cheap-variant) - devtool: "eval-source-map", // 有模块映射(module mappings)的 SourceMap 低级变体 + devtool: 'eval-source-map', // 有模块映射(module mappings)的 SourceMap 低级变体 // devtool: "eval", // 没有模块映射,而是命名模块。以牺牲细节达到最快。 devServer: { - contentBase: [path.join(__dirname, "../dist")], + contentBase: [path.join(__dirname, '../dist')], compress: true, port: 9000, // 启动端口号 hot: true, // 启用 webpack 的模块热替换特性 inline: true, - publicPath: "/", // 和上文 output 的“publicPath”值保持一致 + publicPath: '/', // 和上文 output 的“publicPath”值保持一致 historyApiFallback: true } -}); +}) diff --git a/demos/reactapp/config/webpack.config.prod.js b/demos/reactapp/config/webpack.config.prod.js index fc4ffbf..1b1c2a6 100644 --- a/demos/reactapp/config/webpack.config.prod.js +++ b/demos/reactapp/config/webpack.config.prod.js @@ -1,11 +1,11 @@ /** * Created by Zhang Peng on 2017/6/14. */ -const path = require('path'); -const webpack = require('webpack'); -const webpackMerge = require('webpack-merge'); -const ExtractTextPlugin = require('extract-text-webpack-plugin'); -const baseWebpackConfig = require('./webpack.config.base'); +const path = require('path') +const webpack = require('webpack') +const webpackMerge = require('webpack-merge') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const baseWebpackConfig = require('./webpack.config.base') module.exports = webpackMerge(baseWebpackConfig, { // 这里应用程序开始执行 @@ -14,8 +14,8 @@ module.exports = webpackMerge(baseWebpackConfig, { entry: { main: [ // App 入口 - path.resolve(__dirname, "../src/index"), - ], + path.resolve(__dirname, '../src/index') + ] }, // 关于模块配置 @@ -36,18 +36,18 @@ module.exports = webpackMerge(baseWebpackConfig, { }, { - loader: "image-webpack-loader", + loader: 'image-webpack-loader', query: { progressive: true, pngquant: { - quality: "65-90", + quality: '65-90', speed: 4 } } } ] - }, + } ] }, @@ -68,7 +68,7 @@ module.exports = webpackMerge(baseWebpackConfig, { // 压缩 js 插件 new webpack.optimize.UglifyJsPlugin({ output: { - comments: false, // remove all comments + comments: false // remove all comments }, compress: { warnings: false @@ -76,6 +76,6 @@ module.exports = webpackMerge(baseWebpackConfig, { }), // 将样式文件独立打包 - new ExtractTextPlugin("styles.css"), - ], -}); + new ExtractTextPlugin('styles.css') + ] +}) diff --git a/demos/reactapp/public/index.html b/demos/reactapp/public/index.html index f53f4ba..3ee7a54 100644 --- a/demos/reactapp/public/index.html +++ b/demos/reactapp/public/index.html @@ -3,8 +3,8 @@ <%= htmlWebpackPlugin.options.title %> - - + +
diff --git a/demos/reactapp/scripts/build.sh b/demos/reactapp/scripts/build.sh index ca889b1..2529388 100644 --- a/demos/reactapp/scripts/build.sh +++ b/demos/reactapp/scripts/build.sh @@ -1,4 +1,5 @@ #!/bin/bash + ln -s /app/ck-puck-front/node_modules/ node_modules nvm use 8.1.0 npm set registry http://192.168.51.44 diff --git a/demos/reactapp/src/common/apiutils/ajaxCommon.js b/demos/reactapp/src/common/apiutils/ajaxCommon.js index 0300688..c388f24 100644 --- a/demos/reactapp/src/common/apiutils/ajaxCommon.js +++ b/demos/reactapp/src/common/apiutils/ajaxCommon.js @@ -1,10 +1,9 @@ -import React from 'react'; -import { Modal } from 'antd'; -import _ from 'lodash'; +import { Modal } from 'antd' +import _ from 'lodash' -import { COMMON_REQUEST_ERROR } from '../../redux/constants/commonActionTypes'; +import { COMMON_REQUEST_ERROR } from '../../redux/constants/commonActionTypes' -export const REQ_BASE_URL = '/api'; +export const REQ_BASE_URL = '/api' export const METHODS = { GET: 'GET', @@ -13,29 +12,29 @@ export const METHODS = { PUT: 'PUT', DEL: 'DEL', OPTIONS: 'OPTIONS', - PATCH: 'PATCH', -}; + PATCH: 'PATCH' +} export const REQ_TYPE = { HTML: 'html', JSON: 'json', - JSONP: 'jsonp', -}; + JSONP: 'jsonp' +} export const CACHE_TYPE = { DEFAULT: 'default', NO_STORE: 'no-store', RELOAD: 'reload', NO_CACHE: 'no-cache', - FORCE_CACHE: 'force-cache', -}; + FORCE_CACHE: 'force-cache' +} export const ERROR_HANDLER_TYPE = { NO: 'NO', // ['NO' | undefined | false ] 不处理 SYSTEM: 'SYSTEM', // ['SYSTEM'] 只处理系统预料外的返回(not json) SYSTEM_AND_AUTH: 'SYSTEM_AND_AUTH', // [true, 'SYSTEM_AND_AUTH'] 处理上一步,与 认证失败 (比较常用,所以单独列出,用true) - ALL: 'ALL', // [no errorHandler | 'ALL'] 所有 -}; + ALL: 'ALL' // [no errorHandler | 'ALL'] 所有 +} export const defaultOptions = { url: null, @@ -49,32 +48,32 @@ export const defaultOptions = { }, onError: () => { }, - cache: CACHE_TYPE.NO_CACHE, -}; + cache: CACHE_TYPE.NO_CACHE +} // 在 defaultOptions 基础上多出来的, request plan text,response json export const defaultJsonOptions = _.merge({}, defaultOptions, { headers: { Accept: 'application/json, text/plain, */*', - 'Cache-Control': 'no-cache', + 'Cache-Control': 'no-cache' }, - type: REQ_TYPE.JSON, -}); + type: REQ_TYPE.JSON +}) // 在 defaultJsonOptions 基础上多出来的, request response 皆是 json export const defaultBiJsonOptions = _.merge({}, defaultJsonOptions, { headers: { - 'Content-Type': 'application/json;charset=UTF-8', + 'Content-Type': 'application/json;charset=UTF-8' }, - reqType: REQ_TYPE.JSON, -}); + reqType: REQ_TYPE.JSON +}) // 获取真正请求的 URL export function getRealUrl(url) { if (!!url && !url.startsWith('http')) { - return REQ_BASE_URL + url; + return REQ_BASE_URL + url } - return url; + return url } /** @@ -85,20 +84,25 @@ function _showAuthError() { Modal.error({ title: '认证失败', // eslint-disable-next-line react/jsx-filename-extension - content: (

您现在处于非认证状态!!!
- 如果想保留本页状态,请在 新页面登陆
- { /* 否则在 当前页登陆 。 */ } -

), - }); + content: ( < p > 您现在处于非认证状态!!!< + br / > + 如果想保留本页状态,请在 < a + href = '/login' + target = 'blank' > 新页面登陆 < /a> 。
+ { /* 否则在 当前页登陆 。 */ } + < /p>), +}) + } + /** * 防抖展示认证错误(一段时间内仅一次) * @type {Function} */ const showAuthError = _.debounce(_showAuthError, 500, { leading: true, - trailing: false, -}); + trailing: false +}) /** * 展示服务端错误信息 @@ -107,8 +111,8 @@ const showAuthError = _.debounce(_showAuthError, 500, { function _showServerError(e) { Modal.error({ title: '服务端错误!', - content: `服务端错误。服务端可能未正确部署或由于其他原因响应失败!请保留现场并联系开发人员。错误信息: ${e}`, - }); + content: `服务端错误。服务端可能未正确部署或由于其他原因响应失败!请保留现场并联系开发人员。错误信息: ${e}` + }) } /** @@ -117,8 +121,8 @@ function _showServerError(e) { */ const showServerError = _.debounce(_showServerError, 500, { leading: true, - trailing: false, -}); + trailing: false +}) /** * 包装错误处理。所有服务端应用(非业务)非 ret 预计错误与认证错误统一处理。 @@ -132,35 +136,35 @@ const showServerError = _.debounce(_showServerError, 500, { */ export function wrapErrorHandler(errorHandler, dispatch) { return (e) => { - let handlerLevel = 1000; // 默认都处理 + let handlerLevel = 1000 // 默认都处理 // 先看是否传入 errorHandler,如果传入,则执行用户 errorHandler,并根据处理结果设置新的 handlerLevel if (_.isFunction(errorHandler)) { - handlerLevel = _getErrorHandlerLevel(errorHandler(e)); + handlerLevel = _getErrorHandlerLevel(errorHandler(e)) } if (handlerLevel > 0 && e instanceof XMLHttpRequest) { // 服务端应用(非业务)非 ret 预计错误处理,如 404,400,500,非返回 json 错误 - showServerError(e.responseText); + showServerError(e.responseText) } else if (handlerLevel > 10 && e.ret === -1) { // 认证失败,该登陆未登录 - showAuthError(); + showAuthError() } else if (handlerLevel > 100 && dispatch) { - dispatch({ type: COMMON_REQUEST_ERROR, payload: e }); + dispatch({ type: COMMON_REQUEST_ERROR, payload: e }) } else if (handlerLevel > 100) { - const msg = e.ret ? `[code]${e.ret}, [msg]${e.msg}` : JSON.stringify(e); + const msg = e.ret ? `[code]${e.ret}, [msg]${e.msg}` : JSON.stringify(e) // eslint-disable-next-line no-console - console.error(`请求出错: ${msg}`); + console.error(`请求出错: ${msg}`) } - }; + } } function _getErrorHandlerLevel(type) { if (type === ERROR_HANDLER_TYPE.SYSTEM) { - return 10; + return 10 } else if (type === ERROR_HANDLER_TYPE.SYSTEM_AND_AUTH || type === true) { - return 100; + return 100 } else if (type === ERROR_HANDLER_TYPE.ALL) { - return 1000; + return 1000 } - return 0; + return 0 } diff --git a/demos/reactapp/src/common/apiutils/apiCreator.js b/demos/reactapp/src/common/apiutils/apiCreator.js index dcb59b9..389f70f 100644 --- a/demos/reactapp/src/common/apiutils/apiCreator.js +++ b/demos/reactapp/src/common/apiutils/apiCreator.js @@ -1,37 +1,37 @@ const createApi = fetchFunc => options => (...args) => { - let finalOpts; - const argsName = ['options', 'successCallBack', 'errorCallBack', 'dispatch']; + let finalOpts + const argsName = ['options', 'successCallBack', 'errorCallBack', 'dispatch'] // options 可以是 url,或完整的 options 对象 if (typeof options === 'string') { - finalOpts = { url: options }; + finalOpts = { url: options } } else { - finalOpts = { ...options }; + finalOpts = { ...options } } - const temArgs = {}; + const temArgs = {} if (args) { // args 第一个参数,options 可以忽略 - let i = 0; + let i = 0 if (args[0] !== null && typeof args[0] === 'object') { - i = 1; - finalOpts = Object.assign(finalOpts, args[0]); + i = 1 + finalOpts = Object.assign(finalOpts, args[0]) } // eslint-disable-next-line no-plusplus for (let j = i; j < args.length; j++) { // eslint-disable-next-line no-mixed-operators - temArgs[argsName[j - i + 1]] = args[j]; + temArgs[argsName[j - i + 1]] = args[j] } } if (temArgs.successCallBack) { - finalOpts.onSuccess = temArgs.successCallBack; + finalOpts.onSuccess = temArgs.successCallBack } if (temArgs.errorCallBack) { - finalOpts.onError = temArgs.errorCallBack; + finalOpts.onError = temArgs.errorCallBack } - fetchFunc(finalOpts, temArgs.dispatch); -}; + fetchFunc(finalOpts, temArgs.dispatch) +} -export default createApi; +export default createApi diff --git a/demos/reactapp/src/common/apiutils/errorUtils.js b/demos/reactapp/src/common/apiutils/errorUtils.js index 29e2db6..64d0596 100644 --- a/demos/reactapp/src/common/apiutils/errorUtils.js +++ b/demos/reactapp/src/common/apiutils/errorUtils.js @@ -1,10 +1,10 @@ /** * 错误处理帮助类 */ -import { Message } from 'antd'; -import _ from 'lodash'; +import { Message } from 'antd' +import _ from 'lodash' -import { ERROR_HANDLER_TYPE } from './index'; +import { ERROR_HANDLER_TYPE } from './index' /** * 处理业务类型的错误(-3),通过 message 的方式展现 @@ -13,14 +13,14 @@ import { ERROR_HANDLER_TYPE } from './index'; * @return {boolean} */ export function messageBizError(e, callBack) { - let continueHandler = true; + let continueHandler = true if (e && e.ret === -3) { // 业务错误 - Message.error(e.msg, 4.5); - continueHandler = ERROR_HANDLER_TYPE.NO; + Message.error(e.msg, 4.5) + continueHandler = ERROR_HANDLER_TYPE.NO } if (_.isFunction(callBack)) { - callBack({ error: e }); + callBack({ error: e }) } - return continueHandler; + return continueHandler } diff --git a/demos/reactapp/src/common/apiutils/fetchAJAX.js b/demos/reactapp/src/common/apiutils/fetchAJAX.js index 05205dc..ed1ea8c 100644 --- a/demos/reactapp/src/common/apiutils/fetchAJAX.js +++ b/demos/reactapp/src/common/apiutils/fetchAJAX.js @@ -1,27 +1,28 @@ -import 'isomorphic-fetch'; -import { REQ_TYPE, defaultOptions, defaultJsonOptions, getRealUrl, wrapErrorHandler } from './ajaxCommon'; +import 'isomorphic-fetch' +import { defaultJsonOptions, defaultOptions, getRealUrl, REQ_TYPE, wrapErrorHandler } from './ajaxCommon' function handleStatus(res) { if (res.ok) { - return res; + return res } - throw new Error({ result: res.status }); + throw new Error({ result: res.status }) } + // json 有固定的格式,所以固定处理方法 function handleJson(data) { // noinspection JSUnresolvedVariable if (data.ret === 0) { - return data.data; + return data.data } - throw new Error(data); + throw new Error(data) } export function doFetch(options = {}, dispatch) { const opts = { ...defaultOptions, ...options, - onError: wrapErrorHandler(options.onError, dispatch), - }; + onError: wrapErrorHandler(options.onError, dispatch) + } // 根据配置创建 Request 对象 const req = new Request(getRealUrl(opts.url), { @@ -30,23 +31,23 @@ export function doFetch(options = {}, dispatch) { body: opts.data, cache: opts.cache, redirect: 'follow', - mode: 'cors', - }); + mode: 'cors' + }) if (!__DEV__) { - req.credentials = 'include'; + req.credentials = 'include' } // 请求 // FIXME 应该根据 response 类型自动判断是否 Json 请求 - let tempRes = fetch(req).then(handleStatus); + let tempRes = fetch(req).then(handleStatus) if (options.type === REQ_TYPE.JSON) { - tempRes = tempRes.then(res => res.json()).then(handleJson); + tempRes = tempRes.then(res => res.json()).then(handleJson) } - tempRes.then(options.onSuccess).catch(options.onError); + tempRes.then(options.onSuccess).catch(options.onError) } export function doFetchJson(options = {}, dispatch) { - const opts = { ...defaultJsonOptions, ...options }; - doFetch(opts, dispatch); + const opts = { ...defaultJsonOptions, ...options } + doFetch(opts, dispatch) } diff --git a/demos/reactapp/src/common/apiutils/index.js b/demos/reactapp/src/common/apiutils/index.js index 5f22df4..7ca7b96 100644 --- a/demos/reactapp/src/common/apiutils/index.js +++ b/demos/reactapp/src/common/apiutils/index.js @@ -1,26 +1,26 @@ /** * export 一个 API,底层的实现可能会改(如,切换为 reqwest/superagent/fetch) */ -import { METHODS, REQ_TYPE, CACHE_TYPE, ERROR_HANDLER_TYPE } from './ajaxCommon'; -import { doFetch, doFetchJson, doBiJsonFetch } from './reqwestAJAX'; -import createApi from './apiCreator'; +import { CACHE_TYPE, ERROR_HANDLER_TYPE, METHODS, REQ_TYPE } from './ajaxCommon' +import { doBiJsonFetch, doFetch, doFetchJson } from './reqwestAJAX' +import createApi from './apiCreator' /** * 创建一个 API 函数,结果可以是任何形式。如果是响应是 JSON 会自动转换,类似于 #createFetchJson 结果。
* 但是,请求头不指名 Json : Accept:text/javascript, text/html, application/xml, text/xml, *\/* */ -const createFetch = createApi(doFetch); +const createFetch = createApi(doFetch) /** * 创建一个 API 函数,明确指明函数用于获取 Json 格式数据。如果结果不符合格式会转到错误处理
* 请求头:Accept:application/json, text/plain, *\/* */ -const createFetchJson = createApi(doFetchJson); +const createFetchJson = createApi(doFetchJson) // 创建一个 API 函数, 指明客户端、服务端 内容体(content body)都是 Json 格式。
// 在 #createFetchJson 的基础上添加:Content-Type: application/json;charset=UTF-8,
// 同时,如果请求 data 为 Object类型会通过 JSON.stringify 转换 -const createBiJsonFetch = createApi(doBiJsonFetch); +const createBiJsonFetch = createApi(doBiJsonFetch) /** * 将 api 转换为返回 Promise 方式, 不处理 error。 如果处理 error, 请君自new @@ -28,9 +28,9 @@ const createBiJsonFetch = createApi(doBiJsonFetch); */ const createPromiseAPI = api => (data) => { return new Promise((resolve) => { - api({ data }, rs => resolve(rs)); - }); -}; + api({ data }, rs => resolve(rs)) + }) +} const API = { METHODS, @@ -42,7 +42,7 @@ const API = { createFetch, createFetchJson, createBiJsonFetch, - createPromiseAPI, -}; + createPromiseAPI +} -export default API; +export default API diff --git a/demos/reactapp/src/common/apiutils/reqwestAJAX.js b/demos/reactapp/src/common/apiutils/reqwestAJAX.js index ad940ea..2240f27 100644 --- a/demos/reactapp/src/common/apiutils/reqwestAJAX.js +++ b/demos/reactapp/src/common/apiutils/reqwestAJAX.js @@ -1,58 +1,58 @@ -import reqwest from 'reqwest'; -import _ from 'lodash'; +import reqwest from 'reqwest' +import _ from 'lodash' import { - REQ_TYPE, - METHODS, - defaultOptions, - defaultJsonOptions, defaultBiJsonOptions, + defaultJsonOptions, + defaultOptions, getRealUrl, - wrapErrorHandler, -} from './ajaxCommon'; + METHODS, + REQ_TYPE, + wrapErrorHandler +} from './ajaxCommon' function _doFetch(options = {}, dispatch, defaultMergeOption = {}) { const opts = _.merge({}, defaultMergeOption, options, { url: getRealUrl(options.url), - error: wrapErrorHandler(options.onError, dispatch), - }); + error: wrapErrorHandler(options.onError, dispatch) + }) - const method = opts.method && opts.method.toUpperCase(); - const data = opts.data; + const method = opts.method && opts.method.toUpperCase() + const data = opts.data if (METHODS.GET === method && opts.processData !== false && !_.isString(data)) { // get 请求,配置 processData 不为否,data 不为 String 则预处理 - const newData = { ...data, ts: new Date().getTime() }; // 加入时间戳,防止浏览器缓存 - opts.data = reqwest.toQueryString(newData, true); // traditional 方式,保证数组符合 spring mvc 的传参方式。 + const newData = { ...data, ts: new Date().getTime() } // 加入时间戳,防止浏览器缓存 + opts.data = reqwest.toQueryString(newData, true) // traditional 方式,保证数组符合 spring mvc 的传参方式。 } opts.success = (res) => { - const doSuc = options.onSuccess ? options.onSuccess : defaultOptions.onSuccess; // reqwest 名字不同 + const doSuc = options.onSuccess ? options.onSuccess : defaultOptions.onSuccess // reqwest 名字不同 if (opts.type === REQ_TYPE.JSON || typeof res === 'object') { // noinspection JSUnresolvedVariable if (res.result === 0 || res.ret === 0) { - doSuc(res.data); + doSuc(res.data) } else { - opts.error(res); + opts.error(res) } } else { - doSuc(res); + doSuc(res) } - }; + } - reqwest(opts); + reqwest(opts) } export function doFetch(options = {}, dispatch) { - _doFetch(options, dispatch, defaultOptions); + _doFetch(options, dispatch, defaultOptions) } export function doFetchJson(options = {}, dispatch) { - _doFetch(options, dispatch, defaultJsonOptions); + _doFetch(options, dispatch, defaultJsonOptions) } export function doBiJsonFetch(options = {}, dispatch) { - let opts = options; + let opts = options if (typeof opts.data === 'object') { - opts = { ...options, data: JSON.stringify(opts.data) }; + opts = { ...options, data: JSON.stringify(opts.data) } } - _doFetch(opts, dispatch, defaultBiJsonOptions); + _doFetch(opts, dispatch, defaultBiJsonOptions) } diff --git a/demos/reactapp/src/components/index.js b/demos/reactapp/src/components/index.js index ee4376b..3c53a59 100644 --- a/demos/reactapp/src/components/index.js +++ b/demos/reactapp/src/components/index.js @@ -4,8 +4,8 @@ */ /****************************** 布局组件 ******************************/ -export { default as Header } from './layout/Header/Header'; -export { default as Sidebar } from './layout/Sidebar/Sidebar'; -export { default as Content } from './layout/Content/Content'; -export { default as Footer } from './layout/Footer/Footer'; -export { default as Breadcrumb } from './layout/Breadcrumb/Breadcrumb'; +export { default as Header } from './layout/Header/Header' +export { default as Sidebar } from './layout/Sidebar/Sidebar' +export { default as Content } from './layout/Content/Content' +export { default as Footer } from './layout/Footer/Footer' +export { default as Breadcrumb } from './layout/Breadcrumb/Breadcrumb' diff --git a/demos/reactapp/src/components/layout/Breadcrumb/Breadcrumb.jsx b/demos/reactapp/src/components/layout/Breadcrumb/Breadcrumb.jsx index 7ab8d27..7fb65f3 100644 --- a/demos/reactapp/src/components/layout/Breadcrumb/Breadcrumb.jsx +++ b/demos/reactapp/src/components/layout/Breadcrumb/Breadcrumb.jsx @@ -5,10 +5,10 @@ * @see https://ant.design/components/breadcrumb-cn/ * @see https://ant.design/components/icon-cn/ */ -import { Breadcrumb, Icon } from 'antd'; -import PropTypes from 'prop-types'; -import React from 'react'; -import './Breadcrumb.less'; +import { Breadcrumb, Icon } from 'antd' +import PropTypes from 'prop-types' +import React from 'react' +import './Breadcrumb.less' /** * 面包屑组件 @@ -17,28 +17,28 @@ import './Breadcrumb.less'; class CustomBreadcrumb extends React.PureComponent { static propTypes = { data: PropTypes.array - }; + } static defaultProps = { data: [] - }; + } render() { - const { data } = this.props; + const { data } = this.props const breadcrumbItems = data.map((item) => { return ( - + {item.title} ) - }); + }) return (
- + Home {breadcrumbItems} @@ -47,4 +47,5 @@ class CustomBreadcrumb extends React.PureComponent { ) } } -export default CustomBreadcrumb; + +export default CustomBreadcrumb diff --git a/demos/reactapp/src/components/layout/Breadcrumb/Breadcrumb.less b/demos/reactapp/src/components/layout/Breadcrumb/Breadcrumb.less index d53b7ad..17a8c3f 100644 --- a/demos/reactapp/src/components/layout/Breadcrumb/Breadcrumb.less +++ b/demos/reactapp/src/components/layout/Breadcrumb/Breadcrumb.less @@ -1,6 +1,7 @@ .ant-layout-breadcrumb { z-index: 200; line-height: 64px; + .ant-breadcrumb-link { font-size: 16px; } diff --git a/demos/reactapp/src/components/layout/Content/Content.jsx b/demos/reactapp/src/components/layout/Content/Content.jsx index 1c84fba..5dcfb07 100644 --- a/demos/reactapp/src/components/layout/Content/Content.jsx +++ b/demos/reactapp/src/components/layout/Content/Content.jsx @@ -4,12 +4,12 @@ * @see https://ant.design/components/layout-cn/ * @see https://ant.design/components/card-cn/ */ -import { Card, Layout } from 'antd'; -import React from 'react'; +import { Card, Layout } from 'antd' +import React from 'react' -import './Content.less'; +import './Content.less' -const { Content } = Layout; +const { Content } = Layout /** * 内容布局组件 @@ -30,4 +30,5 @@ class CustomContent extends React.PureComponent { ) } } -export default CustomContent; + +export default CustomContent diff --git a/demos/reactapp/src/components/layout/Footer/Footer.jsx b/demos/reactapp/src/components/layout/Footer/Footer.jsx index 0501bc9..adbce5a 100644 --- a/demos/reactapp/src/components/layout/Footer/Footer.jsx +++ b/demos/reactapp/src/components/layout/Footer/Footer.jsx @@ -3,12 +3,12 @@ * @author Zhang Peng * @see https://ant.design/components/layout-cn/ */ -import { Layout } from 'antd'; -import React from 'react'; +import { Layout } from 'antd' +import React from 'react' -import './index.less'; +import './index.less' -const { Footer } = Layout; +const { Footer } = Layout /** * 底部布局组件 @@ -23,4 +23,5 @@ class CustomFooter extends React.PureComponent { ) } } -export default CustomFooter; + +export default CustomFooter diff --git a/demos/reactapp/src/components/layout/Header/Header.jsx b/demos/reactapp/src/components/layout/Header/Header.jsx index 9873740..f4243a6 100644 --- a/demos/reactapp/src/components/layout/Header/Header.jsx +++ b/demos/reactapp/src/components/layout/Header/Header.jsx @@ -3,18 +3,18 @@ * @author Zhang Peng * @see https://ant.design/components/layout-cn/ */ -import { Avatar, Badge, Col, Dropdown, Icon, Layout, Menu, Popover, Row } from 'antd'; -import React from 'react'; -import { Link, withRouter } from 'react-router-dom'; -import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; -import { bindActionCreators } from 'redux'; +import { Avatar, Badge, Col, Dropdown, Icon, Layout, Menu, Popover, Row } from 'antd' +import React from 'react' +import { Link, withRouter } from 'react-router-dom' +import PropTypes from 'prop-types' +import { connect } from 'react-redux' +import { bindActionCreators } from 'redux' -import './Header.less'; -import Breadcrumb from '../Breadcrumb/Breadcrumb'; -import { fetchProfile, logout } from '../../../redux/actions/auth'; +import './Header.less' +import Breadcrumb from '../Breadcrumb/Breadcrumb' +import { fetchProfile, logout } from '../../../redux/actions/auth' -const { Header } = Layout; +const { Header } = Layout const content = (
@@ -24,19 +24,19 @@ const content = (

Content

Content

-); +) const mapStateToProps = (state) => { - const { auth, menu } = state; + const { auth, menu } = state return { auth: auth ? auth : null, navpath: menu.navpath - }; -}; + } +} const mapDispatchToProps = (dispatch) => { - return { actions: bindActionCreators({ fetchProfile, logout }, dispatch) }; -}; + return { actions: bindActionCreators({ fetchProfile, logout }, dispatch) } +} /** * 顶部布局组件 @@ -47,30 +47,30 @@ class CustomHeader extends React.PureComponent { auth: PropTypes.object, actions: PropTypes.object, navpath: PropTypes.array - }; + } static defaultProps = { auth: null, actions: null, navpath: [] - }; + } componentWillMount() { - const { actions } = this.props; - actions.fetchProfile(); + const { actions } = this.props + actions.fetchProfile() } handleLogOut = () => { - const { actions } = this.props; + const { actions } = this.props actions.logout().payload.promise.then(() => { - this.props.history.replace('/login'); - }); - }; + this.props.history.replace('/login') + }) + } render() { - const { auth, navpath } = this.props; - let username = ''; + const { auth, navpath } = this.props + let username = '' if (auth.user) { - if(auth.user.data) { + if (auth.user.data) { username = auth.user.data.name } } @@ -83,30 +83,30 @@ class CustomHeader extends React.PureComponent { 选项2 - + 注销 - ); + ) return (
- + - + - + - + @@ -115,7 +115,7 @@ class CustomHeader extends React.PureComponent { {username} - + @@ -124,5 +124,6 @@ class CustomHeader extends React.PureComponent { ) } } -export default withRouter(connect(mapStateToProps, mapDispatchToProps)(CustomHeader)); + +export default withRouter(connect(mapStateToProps, mapDispatchToProps)(CustomHeader)) diff --git a/demos/reactapp/src/components/layout/Header/Header.less b/demos/reactapp/src/components/layout/Header/Header.less index 54b974f..7cbd5a6 100644 --- a/demos/reactapp/src/components/layout/Header/Header.less +++ b/demos/reactapp/src/components/layout/Header/Header.less @@ -10,6 +10,7 @@ .header-icon { margin: 0 15px; + i { font-size: 20px; } diff --git a/demos/reactapp/src/components/layout/Sidebar/Sidebar.jsx b/demos/reactapp/src/components/layout/Sidebar/Sidebar.jsx index e4a3812..25decc2 100644 --- a/demos/reactapp/src/components/layout/Sidebar/Sidebar.jsx +++ b/demos/reactapp/src/components/layout/Sidebar/Sidebar.jsx @@ -3,19 +3,19 @@ * @author Zhang Peng * @see https://ant.design/components/layout-cn/ */ -import {Icon, Layout, Menu} from "antd"; -import PropTypes from "prop-types"; -import React from "react"; -import {connect} from "react-redux"; -import {matchPath, withRouter} from "react-router"; -import {Link} from "react-router-dom"; -import {bindActionCreators} from "redux"; +import { Icon, Layout, Menu } from 'antd' +import PropTypes from 'prop-types' +import React from 'react' +import { connect } from 'react-redux' +import { matchPath, withRouter } from 'react-router' +import { Link } from 'react-router-dom' +import { bindActionCreators } from 'redux' -import "./Sidebar.less"; -import logoImg from "./antd.svg"; -import {refreshMenu, refreshNavPath} from "../../../redux/actions/menu"; +import './Sidebar.less' +import logoImg from './antd.svg' +import { refreshMenu, refreshNavPath } from '../../../redux/actions/menu' -const {Sider} = Layout; +const { Sider } = Layout const isActive = (path, history) => { return matchPath(path, { @@ -23,7 +23,7 @@ const isActive = (path, history) => { exact: true, strict: false }) -}; +} /** * 侧边导航栏组件。侧边栏采用的响应式布局方式,页面大小收缩到一定程度,侧边栏会隐藏。 @@ -32,16 +32,16 @@ const isActive = (path, history) => { class CustomSidebar extends React.PureComponent { static propTypes = { items: PropTypes.array - }; + } static defaultProps = { items: [] - }; + } state = { - openKey: "sub0", - activeKey: "menu0", - mode: 'inline', - }; + openKey: 'sub0', + activeKey: 'menu0', + mode: 'inline' + } componentDidMount() { this.props.getAllMenu() @@ -57,68 +57,68 @@ class CustomSidebar extends React.PureComponent { }) } }) - }); + }) } menuClickHandle = (item) => { this.setState({ activeKey: item.key - }); + }) this.props.updateNavPath(item.keyPath, item.key) - }; + } render() { - const {items, history} = this.props; - let {activeKey, openKey} = this.state; + const { items, history } = this.props + let { activeKey, openKey } = this.state const _menuProcess = (nodes, pkey) => { return Array.isArray(nodes) && nodes.map((item, i) => { - const menu = _menuProcess(item.children, item.key); - if (item.url && isActive(item.url, history)) { - activeKey = 'menu' + item.key; - openKey = 'sub' + pkey - } + const menu = _menuProcess(item.children, item.key) + if (item.url && isActive(item.url, history)) { + activeKey = 'menu' + item.key + openKey = 'sub' + pkey + } - switch (item.type) { + switch (item.type) { - case 'SubMenu': - return ( - {item.title}} - > - {menu} - - ); - case 'ItemGroup': - return ( - {item.title}} - > - {menu} - - ); - case 'Divider': - return ( - - ); - case 'Item': - default: - return ( - - { - item.url ? {item.icon && }{item.title} : - {item.icon && }{item.title} - } - - ); - break; - } - }); - }; + case 'SubMenu': + return ( + {item.title}} + > + {menu} + + ) + case 'ItemGroup': + return ( + {item.title}} + > + {menu} + + ) + case 'Divider': + return ( + + ) + case 'Item': + default: + return ( + + { + item.url ? {item.icon && }{item.title} : + {item.icon && }{item.title} + } + + ) + break + } + }) + } - const menu = _menuProcess(items); + const menu = _menuProcess(items) return ( /** diff --git a/demos/reactapp/src/components/layout/Sidebar/antd.svg b/demos/reactapp/src/components/layout/Sidebar/antd.svg index c03bd4a..48e82d0 100644 --- a/demos/reactapp/src/components/layout/Sidebar/antd.svg +++ b/demos/reactapp/src/components/layout/Sidebar/antd.svg @@ -1,32 +1,39 @@ - - - a - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - + + + a + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demos/reactapp/src/containers/Core/CoreContainer.jsx b/demos/reactapp/src/containers/Core/CoreContainer.jsx index 9f7da3b..7cf17f3 100644 --- a/demos/reactapp/src/containers/Core/CoreContainer.jsx +++ b/demos/reactapp/src/containers/Core/CoreContainer.jsx @@ -3,14 +3,14 @@ * @author Zhang Peng * @see https://ant.design/components/layout-cn/ */ -import { Layout } from 'antd'; -import React from 'react'; -import { Redirect, Route } from 'react-router-dom'; +import { Layout } from 'antd' +import React from 'react' +import { Redirect, Route } from 'react-router-dom' -import './CoreContainer.less'; -import { authHOC } from '../../utils'; -import { ChildRoutes } from '../../routes'; -import { Content, Footer, Header, Sidebar } from '../../components'; +import './CoreContainer.less' +import { authHOC } from '../../utils' +import { ChildRoutes } from '../../routes' +import { Content, Footer, Header, Sidebar } from '../../components' /** * 应用的核心容器组件 @@ -21,21 +21,22 @@ class CoreContainer extends React.PureComponent { render() { return ( - + -
+
- + {ChildRoutes.map((route, index) => ( - + ))} -
+
- ); + ) } } -export default CoreContainer; + +export default CoreContainer diff --git a/demos/reactapp/src/containers/Root/ReduxDevTools.jsx b/demos/reactapp/src/containers/Root/ReduxDevTools.jsx index 1f3e0e5..557e315 100644 --- a/demos/reactapp/src/containers/Root/ReduxDevTools.jsx +++ b/demos/reactapp/src/containers/Root/ReduxDevTools.jsx @@ -5,12 +5,12 @@ * @see https://github.com/gaearon/redux-devtools-dock-monitor * @see https://github.com/gaearon/redux-devtools-log-monitor */ -import React from 'react'; +import React from 'react' // Exported from redux-devtools -import { createDevTools } from 'redux-devtools'; +import { createDevTools } from 'redux-devtools' // Monitors are separate packages, and you can make a custom one -import LogMonitor from 'redux-devtools-log-monitor'; -import DockMonitor from 'redux-devtools-dock-monitor'; +import LogMonitor from 'redux-devtools-log-monitor' +import DockMonitor from 'redux-devtools-dock-monitor' /** * Redux 开发工具组件 @@ -25,7 +25,7 @@ const ReduxDevTools = createDevTools( - + -); -export default ReduxDevTools; +) +export default ReduxDevTools diff --git a/demos/reactapp/src/containers/Root/RootContainer.dev.jsx b/demos/reactapp/src/containers/Root/RootContainer.dev.jsx index e757dd9..2df6e0c 100644 --- a/demos/reactapp/src/containers/Root/RootContainer.dev.jsx +++ b/demos/reactapp/src/containers/Root/RootContainer.dev.jsx @@ -3,14 +3,15 @@ * @author Zhang Peng * @see http://gaearon.github.io/react-hot-loader/getstarted/ */ -import React from 'react'; -import { Provider } from 'react-redux'; -import { HashRouter as Router } from 'react-router-dom'; +import React from 'react' +import { Provider } from 'react-redux' +import { HashRouter as Router } from 'react-router-dom' -import Routes from '../../routes'; -import ReduxDevTools from './ReduxDevTools'; -import configureStore from '../../redux/store/configureStore'; -const store = configureStore(); +import Routes from '../../routes' +import ReduxDevTools from './ReduxDevTools' +import configureStore from '../../redux/store/configureStore' + +const store = configureStore() /** * 开发环境的 Root 容器,会包含 Redux 的开发工具 @@ -18,15 +19,16 @@ const store = configureStore(); */ class RootContainer extends React.PureComponent { render() { - if (!this.routes) this.routes = Routes; + if (!this.routes) this.routes = Routes return (
- - + +
- ); + ) } } -export default RootContainer; + +export default RootContainer diff --git a/demos/reactapp/src/containers/Root/RootContainer.jsx b/demos/reactapp/src/containers/Root/RootContainer.jsx index 8b6ccba..17ede52 100644 --- a/demos/reactapp/src/containers/Root/RootContainer.jsx +++ b/demos/reactapp/src/containers/Root/RootContainer.jsx @@ -3,10 +3,10 @@ * @author Zhang Peng * @see http://gaearon.github.io/react-hot-loader/getstarted/ */ -if (process.env.NODE_ENV === "development") { - module.exports = require('./RootContainer.dev'); - console.log('[development] Root.dev started.'); +if (process.env.NODE_ENV === 'development') { + module.exports = require('./RootContainer.dev') + console.log('[development] Root.dev started.') } else { - module.exports = require('./RootContainer.prod'); - console.log('[production] Root.prod started.'); + module.exports = require('./RootContainer.prod') + console.log('[production] Root.prod started.') } diff --git a/demos/reactapp/src/containers/Root/RootContainer.prod.jsx b/demos/reactapp/src/containers/Root/RootContainer.prod.jsx index ef87fa3..ae6550f 100644 --- a/demos/reactapp/src/containers/Root/RootContainer.prod.jsx +++ b/demos/reactapp/src/containers/Root/RootContainer.prod.jsx @@ -3,13 +3,14 @@ * @author Zhang Peng * @see http://gaearon.github.io/react-hot-loader/getstarted/ */ -import React from 'react'; -import { Provider } from 'react-redux'; -import { HashRouter as Router } from 'react-router-dom'; +import React from 'react' +import { Provider } from 'react-redux' +import { HashRouter as Router } from 'react-router-dom' -import Routes from '../../routes'; -import configureStore from '../../redux/store/configureStore'; -const store = configureStore(); +import Routes from '../../routes' +import configureStore from '../../redux/store/configureStore' + +const store = configureStore() /** * 生产环境的 Root 容器 @@ -17,12 +18,13 @@ const store = configureStore(); */ class RootContainer extends React.PureComponent { render() { - if (!this.routes) this.routes = Routes; + if (!this.routes) this.routes = Routes return ( - + - ); + ) } } -export default RootContainer; + +export default RootContainer diff --git a/demos/reactapp/src/index.jsx b/demos/reactapp/src/index.jsx index 5e63304..611a6ab 100644 --- a/demos/reactapp/src/index.jsx +++ b/demos/reactapp/src/index.jsx @@ -3,29 +3,29 @@ * @author Zhang Peng * @see http://gaearon.github.io/react-hot-loader/getstarted/ */ -import 'react-hot-loader/patch'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import { AppContainer } from 'react-hot-loader'; +import 'react-hot-loader/patch' +import React from 'react' +import ReactDOM from 'react-dom' +import { AppContainer } from 'react-hot-loader' -import RootContainer from './containers/Root/RootContainer'; +import RootContainer from './containers/Root/RootContainer' const render = Component => { ReactDOM.render( - + , document.getElementById('root') - ); -}; + ) +} // 初次启动 App -render(RootContainer); +render(RootContainer) // 热替换启动 App if (module.hot) { module.hot.accept('./containers/Root/RootContainer', () => { - const NextRootContainer = require('./containers/Root/RootContainer'); + const NextRootContainer = require('./containers/Root/RootContainer') render(NextRootContainer) - }); + }) } diff --git a/demos/reactapp/src/redux/actions/auth.js b/demos/reactapp/src/redux/actions/auth.js index ef11ea7..691ba72 100644 --- a/demos/reactapp/src/redux/actions/auth.js +++ b/demos/reactapp/src/redux/actions/auth.js @@ -1,11 +1,11 @@ -const webapi = require('../../webapi'); -import { FETCH_PROFILE, LOGIN, LOGOUT, UID_NOT_FOUND } from '../constants/authActionType'; +const webapi = require('../../webapi') +import { FETCH_PROFILE, LOGIN, LOGOUT, UID_NOT_FOUND } from '../constants/authActionType' export const fetchProfile = () => { - let uid = window.localStorage.getItem('uid'); + let uid = window.localStorage.getItem('uid') if (uid === undefined) { - return { type: UID_NOT_FOUND }; + return { type: UID_NOT_FOUND } } return { @@ -14,7 +14,7 @@ export const fetchProfile = () => { promise: webapi.get('/my') } } -}; +} export const login = (username, password) => { return { @@ -26,7 +26,7 @@ export const login = (username, password) => { }) } } -}; +} export const logout = () => { return { @@ -35,4 +35,4 @@ export const logout = () => { promise: webapi.get('/logout') } } -}; +} diff --git a/demos/reactapp/src/redux/actions/menu.js b/demos/reactapp/src/redux/actions/menu.js index 308a3b5..32fb133 100644 --- a/demos/reactapp/src/redux/actions/menu.js +++ b/demos/reactapp/src/redux/actions/menu.js @@ -1,5 +1,5 @@ -const webapi = require('../../webapi'); -import { REFRESH_MENU, REFRESH_NAVPATH } from '../constants/menuActionType'; +const webapi = require('../../webapi') +import { REFRESH_MENU, REFRESH_NAVPATH } from '../constants/menuActionType' export const refreshNavPath = (path, key) => { return { @@ -9,7 +9,7 @@ export const refreshNavPath = (path, key) => { key: key } } -}; +} export const refreshMenu = () => { return { @@ -18,4 +18,4 @@ export const refreshMenu = () => { promise: webapi.get('/menu') } } -}; +} diff --git a/demos/reactapp/src/redux/constants/authActionType.js b/demos/reactapp/src/redux/constants/authActionType.js index 18e4b67..231f4f0 100644 --- a/demos/reactapp/src/redux/constants/authActionType.js +++ b/demos/reactapp/src/redux/constants/authActionType.js @@ -1,16 +1,16 @@ -export const LOGIN = 'LOGIN'; -export const LOGOUT = 'LOGOUT'; -export const FETCH_PROFILE = 'FETCH_PROFILE'; -export const UID_NOT_FOUND = 'UID_NOT_FOUND'; +export const LOGIN = 'LOGIN' +export const LOGOUT = 'LOGOUT' +export const FETCH_PROFILE = 'FETCH_PROFILE' +export const UID_NOT_FOUND = 'UID_NOT_FOUND' -export const LOGIN_PENDING = 'LOGIN_PENDING'; -export const LOGIN_SUCCESS = 'LOGIN_SUCCESS'; -export const LOGIN_FAILED = 'LOGIN_FAILED'; +export const LOGIN_PENDING = 'LOGIN_PENDING' +export const LOGIN_SUCCESS = 'LOGIN_SUCCESS' +export const LOGIN_FAILED = 'LOGIN_FAILED' -export const LOGOUT_PENDING = 'LOGOUT_PENDING'; -export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS'; -export const LOGOUT_FAILED = 'LOGOUT_FAILED'; +export const LOGOUT_PENDING = 'LOGOUT_PENDING' +export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS' +export const LOGOUT_FAILED = 'LOGOUT_FAILED' -export const FETCH_PROFILE_PENDING = 'FETCH_PROFILE_PENDING'; -export const FETCH_PROFILE_SUCCESS = 'FETCH_PROFILE_SUCCESS'; -export const FETCH_PROFILE_FAILED = 'FETCH_PROFILE_FAILED'; +export const FETCH_PROFILE_PENDING = 'FETCH_PROFILE_PENDING' +export const FETCH_PROFILE_SUCCESS = 'FETCH_PROFILE_SUCCESS' +export const FETCH_PROFILE_FAILED = 'FETCH_PROFILE_FAILED' diff --git a/demos/reactapp/src/redux/constants/commonActionTypes.js b/demos/reactapp/src/redux/constants/commonActionTypes.js index 42df126..3a23b63 100644 --- a/demos/reactapp/src/redux/constants/commonActionTypes.js +++ b/demos/reactapp/src/redux/constants/commonActionTypes.js @@ -4,27 +4,27 @@ * 如果无 dispatch,则 console.log error * @type {string} */ -export const COMMON_REQUEST_ERROR = 'COMMON_REQUEST_ERROR'; +export const COMMON_REQUEST_ERROR = 'COMMON_REQUEST_ERROR' /** * 公共的 SpinModal action。用于控制统一的过度形式的模态框展示。 * 各类型,配合 payload 中的 type 等字段控制。 * @type {string} */ -export const COMMON_SPIN_MODAL = 'COMMON_SPIN_MODAL'; +export const COMMON_SPIN_MODAL = 'COMMON_SPIN_MODAL' /** * 公共的 SpinModal action。用于控制统一的过度形式的模态框消失。 * @type {string} */ -export const COMMON_SPIN_MODAL_DIS = 'COMMON_SPIN_MODAL_DIS'; +export const COMMON_SPIN_MODAL_DIS = 'COMMON_SPIN_MODAL_DIS' // 校验 -export const COMMON_VALIDATE_FAIL = 'COMMON_VALIDATE_FAIL'; +export const COMMON_VALIDATE_FAIL = 'COMMON_VALIDATE_FAIL' /** * 公共的页面离开(跳转)确认功能开关 * @type {string} */ -export const COMMON_LEAVE_CONFIRM_ON = 'COMMON_LEAVE_CONFIRM_ON'; -export const COMMON_LEAVE_CONFIRM_OFF = 'COMMON_LEAVE_CONFIRM_OFF'; +export const COMMON_LEAVE_CONFIRM_ON = 'COMMON_LEAVE_CONFIRM_ON' +export const COMMON_LEAVE_CONFIRM_OFF = 'COMMON_LEAVE_CONFIRM_OFF' diff --git a/demos/reactapp/src/redux/constants/menuActionType.js b/demos/reactapp/src/redux/constants/menuActionType.js index 0d0774b..d5aa48c 100644 --- a/demos/reactapp/src/redux/constants/menuActionType.js +++ b/demos/reactapp/src/redux/constants/menuActionType.js @@ -1,4 +1,4 @@ -export const REFRESH_MENU = 'REFRESH_MENU'; -export const REFRESH_NAVPATH = 'REFRESH_NAVPATH'; -export const REFRESH_MENU_SUCCESS = 'REFRESH_MENU_SUCCESS'; -export const REFRESH_MENU_FAILED = 'REFRESH_MENU_FAILED'; +export const REFRESH_MENU = 'REFRESH_MENU' +export const REFRESH_NAVPATH = 'REFRESH_NAVPATH' +export const REFRESH_MENU_SUCCESS = 'REFRESH_MENU_SUCCESS' +export const REFRESH_MENU_FAILED = 'REFRESH_MENU_FAILED' diff --git a/demos/reactapp/src/redux/middlewares/promiseMiddleware.js b/demos/reactapp/src/redux/middlewares/promiseMiddleware.js index 7849820..1fd4e12 100644 --- a/demos/reactapp/src/redux/middlewares/promiseMiddleware.js +++ b/demos/reactapp/src/redux/middlewares/promiseMiddleware.js @@ -1,25 +1,25 @@ -const defaultTypes = ['PENDING', 'FULFILLED', 'REJECTED']; +const defaultTypes = ['PENDING', 'FULFILLED', 'REJECTED'] const isPromise = (value) => { if (value !== null && typeof value === 'object') { - return value.promise && typeof value.promise.then === 'function'; + return value.promise && typeof value.promise.then === 'function' } -}; +} function createPromiseMiddleware(config = {}) { - const promiseTypeSuffixes = config.promiseTypeSuffixes || defaultTypes; + const promiseTypeSuffixes = config.promiseTypeSuffixes || defaultTypes return (_ref) => { - const dispatch = _ref.dispatch; + const dispatch = _ref.dispatch return next => action => { if (!isPromise(action.payload)) { - return next(action); + return next(action) } - const { type, payload, meta } = action; - const { promise, data } = payload; - const [PENDING, FULFILLED, REJECTED] = (meta || {}).promiseTypeSuffixes || promiseTypeSuffixes; + const { type, payload, meta } = action + const { promise, data } = payload + const [PENDING, FULFILLED, REJECTED] = (meta || {}).promiseTypeSuffixes || promiseTypeSuffixes /** * Dispatch the first async handler. This tells the @@ -29,15 +29,15 @@ function createPromiseMiddleware(config = {}) { type: `${type}_${PENDING}`, ...!!data ? { payload: data } : {}, ...!!meta ? { meta } : {} - }); + }) - const isAction = resolved => resolved && (resolved.meta || resolved.payload); - const isThunk = resolved => typeof resolved === 'function'; + const isAction = resolved => resolved && (resolved.meta || resolved.payload) + const isThunk = resolved => typeof resolved === 'function' const getResolveAction = isError => ({ type: `${type}_${isError ? REJECTED : FULFILLED}`, ...!!meta ? { meta } : {}, ...!!isError ? { error: true } : {} - }); + }) /** * Re-dispatch one of: @@ -47,29 +47,29 @@ function createPromiseMiddleware(config = {}) { */ action.payload.promise = promise.then( (resolved = {}) => { - const resolveAction = getResolveAction(); + const resolveAction = getResolveAction() return dispatch(isThunk(resolved) ? resolved.bind(null, resolveAction) : { ...resolveAction, ...isAction(resolved) ? resolved : { ...!!resolved && { payload: resolved } } - }); + }) }, (rejected = {}) => { - const resolveAction = getResolveAction(true); + const resolveAction = getResolveAction(true) return dispatch(isThunk(rejected) ? rejected.bind(null, resolveAction) : { ...resolveAction, ...isAction(rejected) ? rejected : { ...!!rejected && { payload: rejected } } - }); - }, - ); + }) + } + ) - return action; - }; - }; + return action + } + } } -const promise = createPromiseMiddleware({ promiseTypeSuffixes: ['PENDING', 'SUCCESS', 'FAILED'] }); -export default promise; +const promise = createPromiseMiddleware({ promiseTypeSuffixes: ['PENDING', 'SUCCESS', 'FAILED'] }) +export default promise diff --git a/demos/reactapp/src/redux/reducers/auth.js b/demos/reactapp/src/redux/reducers/auth.js index 2b48b1d..3b400dc 100644 --- a/demos/reactapp/src/redux/reducers/auth.js +++ b/demos/reactapp/src/redux/reducers/auth.js @@ -4,52 +4,52 @@ import { LOGIN_PENDING, LOGIN_SUCCESS, LOGOUT_SUCCESS -} from '../constants/authActionType'; +} from '../constants/authActionType' const initialState = { user: null, loggingIn: false, loggingOut: false, message: null -}; +} const auth = (state = initialState, action = {}) => { switch (action.type) { case LOGIN_PENDING: return Object.assign({}, state, { loggingIn: true - }); + }) case LOGIN_SUCCESS: - let user = action.payload.data; - window.localStorage.setItem('uid', user.uid); + let user = action.payload.data + window.localStorage.setItem('uid', user.uid) return Object.assign({}, state, { user: user, loggingIn: false, message: null - }); + }) case LOGIN_FAILED: return { ...state, loggingIn: false, user: null, message: action.payload.response.data.message - }; + } case LOGOUT_SUCCESS: - window.localStorage.removeItem('uid'); + window.localStorage.removeItem('uid') return { ...state, loggingOut: false, user: null, message: null - }; + } case FETCH_PROFILE_SUCCESS: return Object.assign({}, state, { user: action.payload.data, loggingIn: false, message: null - }); + }) default: - return state; + return state } -}; -export default auth; +} +export default auth diff --git a/demos/reactapp/src/redux/reducers/index.js b/demos/reactapp/src/redux/reducers/index.js index 18177cc..1494df4 100644 --- a/demos/reactapp/src/redux/reducers/index.js +++ b/demos/reactapp/src/redux/reducers/index.js @@ -1,12 +1,12 @@ /** * Created by Zhang Peng on 2017/7/6. */ -import { combineReducers } from 'redux'; -import auth from './auth'; -import menu from './menu'; +import { combineReducers } from 'redux' +import auth from './auth' +import menu from './menu' const rootReducer = combineReducers({ auth, menu -}); -export default rootReducer; +}) +export default rootReducer diff --git a/demos/reactapp/src/redux/reducers/menu.js b/demos/reactapp/src/redux/reducers/menu.js index bb4a781..d825949 100644 --- a/demos/reactapp/src/redux/reducers/menu.js +++ b/demos/reactapp/src/redux/reducers/menu.js @@ -1,49 +1,49 @@ -import _ from 'lodash'; +import _ from 'lodash' -import { REFRESH_MENU_SUCCESS, REFRESH_NAVPATH } from '../constants/menuActionType'; +import { REFRESH_MENU_SUCCESS, REFRESH_NAVPATH } from '../constants/menuActionType' const initialState = { items: [], navpath: [] -}; +} const menu = (state = initialState, action = {}) => { switch (action.type) { case REFRESH_MENU_SUCCESS: return Object.assign({}, initialState, { items: action.payload.data.data - }); + }) case REFRESH_NAVPATH: - let navpath = [], tmpOb, tmpKey, children; + let navpath = [], tmpOb, tmpKey, children if (Array.isArray(action.payload.data)) { action.payload.data.reverse().map((item) => { if (item.indexOf('sub') !== -1) { - tmpKey = item.replace('sub', ''); - tmpOb = _.find(state.items, function (o) { - return o.key == tmpKey; - }); - children = tmpOb.children; + tmpKey = item.replace('sub', '') + tmpOb = _.find(state.items, function(o) { + return o.key == tmpKey + }) + children = tmpOb.children navpath.push({ key: tmpOb.key, title: tmpOb.title, icon: tmpOb.icon, type: tmpOb.type, - url: tmpOb.url, + url: tmpOb.url }) } if (item.indexOf('menu') !== -1) { - tmpKey = item.replace('menu', ''); + tmpKey = item.replace('menu', '') if (children) { - tmpOb = _.find(children, function (o) { - return o.key == tmpKey; - }); + tmpOb = _.find(children, function(o) { + return o.key == tmpKey + }) navpath.push({ key: tmpOb.key, title: tmpOb.title, icon: tmpOb.icon, type: tmpOb.type, - url: tmpOb.url, - }); + url: tmpOb.url + }) } } }) @@ -51,9 +51,9 @@ const menu = (state = initialState, action = {}) => { return Object.assign({}, state, { currentIndex: action.payload.key * 1, navpath: navpath - }); + }) default: - return state; + return state } -}; -export default menu; +} +export default menu diff --git a/demos/reactapp/src/redux/store/configureStore.dev.js b/demos/reactapp/src/redux/store/configureStore.dev.js index a4f48e3..d0d1c57 100644 --- a/demos/reactapp/src/redux/store/configureStore.dev.js +++ b/demos/reactapp/src/redux/store/configureStore.dev.js @@ -4,14 +4,14 @@ * @see https://github.com/gaearon/redux-devtools/blob/master/docs/Walkthrough.md */ -import { applyMiddleware, compose, createStore } from 'redux'; -import { persistState } from 'redux-devtools'; -import logger from 'redux-logger'; -import thunk from 'redux-thunk'; +import { applyMiddleware, compose, createStore } from 'redux' +import { persistState } from 'redux-devtools' +import logger from 'redux-logger' +import thunk from 'redux-thunk' -import DevTools from '../../containers/Root/ReduxDevTools'; -import promise from '../middlewares/promiseMiddleware'; -import reducers from '../reducers'; +import DevTools from '../../containers/Root/ReduxDevTools' +import promise from '../middlewares/promiseMiddleware' +import reducers from '../reducers' const enhancer = compose( // Middleware you want to use in development: @@ -20,13 +20,13 @@ const enhancer = compose( DevTools.instrument(), // Optional. Lets you write ?debug_session= in address bar to persist debug sessions persistState(getDebugSessionKey()) -); +) function getDebugSessionKey() { // You can write custom logic here! // By default we try to read the key from ?debug_session= in the address bar - const matches = window.location.href.match(/[?&]debug_session=([^&]+)\b/); - return (matches && matches.length > 0) ? matches[1] : null; + const matches = window.location.href.match(/[?&]debug_session=([^&]+)\b/) + return (matches && matches.length > 0) ? matches[1] : null } /** @@ -37,15 +37,16 @@ function getDebugSessionKey() { function configureStore(initialState) { // Note: only Redux >= 3.1.0 supports passing enhancer as third argument. // See https://github.com/reactjs/redux/releases/tag/v3.1.0 - const store = createStore(reducers, initialState, enhancer); + const store = createStore(reducers, initialState, enhancer) // Hot reload reducers (requires Webpack or Browserify HMR to be enabled) if (module.hot) { module.hot.accept('../reducers', () => store.replaceReducer(require('../reducers')) - ); + ) } - return store; + return store } -export default configureStore; + +export default configureStore diff --git a/demos/reactapp/src/redux/store/configureStore.js b/demos/reactapp/src/redux/store/configureStore.js index 06dc904..4dc34e5 100644 --- a/demos/reactapp/src/redux/store/configureStore.js +++ b/demos/reactapp/src/redux/store/configureStore.js @@ -6,7 +6,7 @@ // Use DefinePlugin (Webpack) or loose-envify (Browserify) // together with Uglify to strip the dev branch in prod build. if (process.env.NODE_ENV === 'development') { - module.exports = require('./configureStore.dev').default; + module.exports = require('./configureStore.dev').default } else { - module.exports = require('./configureStore.prod').default; + module.exports = require('./configureStore.prod').default } diff --git a/demos/reactapp/src/redux/store/configureStore.prod.js b/demos/reactapp/src/redux/store/configureStore.prod.js index f6ff995..b8095c8 100644 --- a/demos/reactapp/src/redux/store/configureStore.prod.js +++ b/demos/reactapp/src/redux/store/configureStore.prod.js @@ -4,13 +4,13 @@ * @see https://github.com/gaearon/redux-devtools/blob/master/docs/Walkthrough.md */ -import { applyMiddleware, createStore } from 'redux'; -import thunk from 'redux-thunk'; +import { applyMiddleware, createStore } from 'redux' +import thunk from 'redux-thunk' -import promise from '../middlewares/promiseMiddleware'; -import reducers from '../reducers'; +import promise from '../middlewares/promiseMiddleware' +import reducers from '../reducers' -const enhancer = applyMiddleware(thunk, promise); +const enhancer = applyMiddleware(thunk, promise) /** * 生产环境的 Store 构造方法。 @@ -18,6 +18,7 @@ const enhancer = applyMiddleware(thunk, promise); * @returns {Store} Redux 的状态容器,一个应用只有一个 */ function configureStore(initialState) { - return createStore(reducers, initialState, enhancer); + return createStore(reducers, initialState, enhancer) } -export default configureStore; + +export default configureStore diff --git a/demos/reactapp/src/routes/index.jsx b/demos/reactapp/src/routes/index.jsx index 0f987ab..1b6965a 100644 --- a/demos/reactapp/src/routes/index.jsx +++ b/demos/reactapp/src/routes/index.jsx @@ -5,11 +5,11 @@ * @see https://reacttraining.com/react-router/ * @see https://reacttraining.cn/ */ -import React from 'react'; -import { Route, Switch } from 'react-router-dom'; +import React from 'react' +import { Route, Switch } from 'react-router-dom' -import CoreContainer from '../containers/Core'; -import Login from '../views/pages/login/Login'; +import CoreContainer from '../containers/Core' +import Login from '../views/pages/login/Login' /** * 子路由表 @@ -28,7 +28,7 @@ export const ChildRoutes = [ 'path': '/pages/user', 'component': require('../views/pages/user/User').default } -]; +] /** * 默认路由 @@ -36,8 +36,8 @@ export const ChildRoutes = [ */ const Routes = ( - - + + -); -export default Routes; +) +export default Routes diff --git a/demos/reactapp/src/utils/asyncLoadHOC.js b/demos/reactapp/src/utils/asyncLoadHOC.js index ae62f9a..eb544b2 100644 --- a/demos/reactapp/src/utils/asyncLoadHOC.js +++ b/demos/reactapp/src/utils/asyncLoadHOC.js @@ -4,34 +4,40 @@ * @see https://segmentfault.com/a/1190000009820646 */ -import React from 'react'; +import React from 'react' -let Component = null; +let Component = null export const asyncLoadHOC = loadComponent => ( class AsyncComponent extends React.Component { static hasLoadedComponent() { - return Component !== null; + return Component !== null } componentWillMount() { if (AsyncComponent.hasLoadedComponent()) { - return; + return } loadComponent().then( module => module.default ).then((comp) => { - Component = comp; + Component = comp }).catch((err) => { - console.error(`Cannot load component in `); - throw err; - }); + console.error(`Cannot load component in `) + throw err + }) } render() { - return (Component) ? : null; + return (Component) ? + < + Component + {... + this.props + } + /> : null; } } -); +) diff --git a/demos/reactapp/src/utils/authHOC.jsx b/demos/reactapp/src/utils/authHOC.jsx index 25973a4..94554e1 100644 --- a/demos/reactapp/src/utils/authHOC.jsx +++ b/demos/reactapp/src/utils/authHOC.jsx @@ -5,8 +5,8 @@ * @see https://zhuanlan.zhihu.com/p/24776678 * @see https://segmentfault.com/a/1190000004598113 */ -import React from 'react'; -import { withRouter } from 'react-router-dom'; +import React from 'react' +import { withRouter } from 'react-router-dom' /** * 校验方法 @@ -14,12 +14,12 @@ import { withRouter } from 'react-router-dom'; * @param props {PropsType} 组件的props */ const validate = props => { - const { history } = props; - const isLoggedIn = !!window.localStorage.getItem("uid"); - if (!isLoggedIn && history.location.pathname !== "/login") { - history.replace("/login"); + const { history } = props + const isLoggedIn = !!window.localStorage.getItem('uid') + if (!isLoggedIn && history.location.pathname !== '/login') { + history.replace('/login') } -}; +} /** * 对组件进行认证的方法 @@ -30,19 +30,20 @@ const validate = props => { const authHOC = WrappedComponent => { class Authenticate extends React.Component { componentWillMount() { - validate(this.props); + validate(this.props) } componentWillReceiveProps(nextProps) { if (nextProps.location !== this.props.location) { - validate(nextProps); + validate(nextProps) } } render() { - return ; + return } } - return withRouter(Authenticate); -}; -export default authHOC; + + return withRouter(Authenticate) +} +export default authHOC diff --git a/demos/reactapp/src/utils/http.js b/demos/reactapp/src/utils/http.js index 8472c25..db936b7 100644 --- a/demos/reactapp/src/utils/http.js +++ b/demos/reactapp/src/utils/http.js @@ -5,18 +5,18 @@ * @see http://www.jianshu.com/p/df464b26ae58 */ -const axios = require('axios'); -const qs = require('qs'); +const axios = require('axios') +const qs = require('qs') -import config from '../../config/app.config'; +import config from '../../config/app.config' // 本项目中 axios 的默认全局配置 -axios.defaults.timeout = config.http.timeout; -axios.defaults.baseURL = config.http.baseURL; +axios.defaults.timeout = config.http.timeout +axios.defaults.baseURL = config.http.baseURL -axios.defaults.headers.get['Content-Type'] = 'application/json'; -axios.defaults.headers.post['Content-Type'] = 'application/json'; -axios.defaults.headers.put['Content-Type'] = 'application/json'; +axios.defaults.headers.get['Content-Type'] = 'application/json' +axios.defaults.headers.post['Content-Type'] = 'application/json' +axios.defaults.headers.put['Content-Type'] = 'application/json' // 本项目的默认配置 const defaultConfig = { @@ -34,20 +34,20 @@ const defaultConfig = { //该选项只适用于以下请求方式:`put/post/patch` //数组里面的最后一个函数必须返回一个字符串、-一个`ArrayBuffer`或者`Stream` - transformRequest: [function (data) { + transformRequest: [function(data) { // 序列化 if (data) { - console.log("[request after stringify] data: ", JSON.stringify(data)); - return JSON.stringify(data); + console.log('[request after stringify] data: ', JSON.stringify(data)) + return JSON.stringify(data) } }], //`transformResponse` 选项允许我们在数据传送到`then/catch`方法之前对数据进行改动 - transformResponse: [function (data) { + transformResponse: [function(data) { // 反序列化 if (data) { - console.log("[response after parse] data: ", JSON.parse(data)); - return JSON.parse(data); + console.log('[response after parse] data: ', JSON.parse(data)) + return JSON.parse(data) } }], @@ -62,10 +62,10 @@ const defaultConfig = { //`paramsSerializer`是一个可选的函数,起作用是让参数(params)序列化 //例如(https://www.npmjs.com/package/qs,http://api.jquery.com/jquery.param) - paramsSerializer: function (params) { - const content = qs.stringify(params, { arrayFormat: 'brackets' }); - console.log("[http] params 序列化后:", content); - return content; + paramsSerializer: function(params) { + const content = qs.stringify(params, { arrayFormat: 'brackets' }) + console.log('[http] params 序列化后:', content) + return content }, //`data`选项是作为一个请求体而需要被发送的数据 @@ -107,11 +107,11 @@ const defaultConfig = { xsrfHeaderName: 'X-XSRF-TOKEN',//default //`onUploadProgress`上传进度事件 - onUploadProgress: function (progressEvent) { + onUploadProgress: function(progressEvent) { }, //下载进度的事件 - onDownloadProgress: function (progressEvent) { + onDownloadProgress: function(progressEvent) { }, //相应内容的最大值 @@ -119,9 +119,9 @@ const defaultConfig = { //`validateStatus`定义了是否根据http相应状态码,来resolve或者reject promise //如果`validateStatus`返回true(或者设置为`null`或者`undefined`),那么promise的状态将会是resolved,否则其状态就是rejected - validateStatus: function (status) { - return status >= 200 && status < 300;//default - }, + validateStatus: function(status) { + return status >= 200 && status < 300//default + } //`maxRedirects`定义了在nodejs中重定向的最大数量 // maxRedirects: 5,//default @@ -147,7 +147,7 @@ const defaultConfig = { //详见cancelation部分 // cancelToken: new CancelToken(function (cancel) { // }) -}; +} // 使用默认配置初始化的请求 -const http = axios.create(defaultConfig); -export default http; +const http = axios.create(defaultConfig) +export default http diff --git a/demos/reactapp/src/utils/index.jsx b/demos/reactapp/src/utils/index.jsx index d3f1eba..bf5aea9 100644 --- a/demos/reactapp/src/utils/index.jsx +++ b/demos/reactapp/src/utils/index.jsx @@ -5,4 +5,4 @@ * @author Zhang Peng */ -export { default as authHOC } from './authHOC'; +export { default as authHOC } from './authHOC' diff --git a/demos/reactapp/src/views/pages/home/Home.jsx b/demos/reactapp/src/views/pages/home/Home.jsx index c518924..e3bc8b6 100644 --- a/demos/reactapp/src/views/pages/home/Home.jsx +++ b/demos/reactapp/src/views/pages/home/Home.jsx @@ -1,27 +1,26 @@ /** * Created by Zhang Peng on 2017/7/21. */ -import React from 'react'; -import {Carousel, Col, Row} from 'antd'; -import './Home.less'; +import React from 'react' +import './Home.less' -import logo from './logo.svg'; +import logo from './logo.svg' export default class Home extends React.Component { - static propTypes = {}; - static defaultProps = {}; + static propTypes = {} + static defaultProps = {} render() { return (
- logo + logo

Welcome to REACT ADMIN

REACT ADMIN is developing。。。

- ); + ) } } diff --git a/demos/reactapp/src/views/pages/home/Home.less b/demos/reactapp/src/views/pages/home/Home.less index e3a820d..512b794 100644 --- a/demos/reactapp/src/views/pages/home/Home.less +++ b/demos/reactapp/src/views/pages/home/Home.less @@ -24,6 +24,10 @@ } @keyframes App-logo-spin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } diff --git a/demos/reactapp/src/views/pages/home/logo.svg b/demos/reactapp/src/views/pages/home/logo.svg index 3f454eb..6d75536 100644 --- a/demos/reactapp/src/views/pages/home/logo.svg +++ b/demos/reactapp/src/views/pages/home/logo.svg @@ -1,6 +1,7 @@ - + diff --git a/demos/reactapp/src/views/pages/login/Login.jsx b/demos/reactapp/src/views/pages/login/Login.jsx index b016b90..33289c1 100644 --- a/demos/reactapp/src/views/pages/login/Login.jsx +++ b/demos/reactapp/src/views/pages/login/Login.jsx @@ -1,95 +1,96 @@ -import { Button, Card, Col, Form, Icon, Input, message, Row } from 'antd'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import { withRouter } from 'react-router-dom'; -import { bindActionCreators } from 'redux'; +import { Button, Card, Col, Form, Icon, Input, message, Row } from 'antd' +import PropTypes from 'prop-types' +import React from 'react' +import { connect } from 'react-redux' +import { withRouter } from 'react-router-dom' +import { bindActionCreators } from 'redux' -import { login } from '../../../redux/actions/auth'; -import loginLogo from './login-logo.png'; +import { login } from '../../../redux/actions/auth' +import loginLogo from './login-logo.png' -import './Login.less'; +import './Login.less' -const FormItem = Form.Item; +const FormItem = Form.Item const propTypes = { user: PropTypes.object, loggingIn: PropTypes.bool, message: PropTypes.string -}; +} + function hasErrors(fieldsError) { - return Object.keys(fieldsError).some(field => fieldsError[field]); + return Object.keys(fieldsError).some(field => fieldsError[field]) } class Login extends React.Component { constructor(props) { - super(props); + super(props) this.state = { - loading: false, + loading: false } } componentDidMount() { // To disabled submit button at the beginning. - this.props.form.validateFields(); + this.props.form.validateFields() } handleSubmit(e) { - e.preventDefault(); + e.preventDefault() this.setState({ loading: true - }); + }) - const data = this.props.form.getFieldsValue(); + const data = this.props.form.getFieldsValue() this.props.login(data.user, data.password).payload.promise.then(response => { this.setState({ loading: false - }); + }) if (response.error) { - console.warn('login failed: ', response.payload.message); + console.warn('login failed: ', response.payload.message) } else { - let result = response.payload.data; - console.log("login result:", result); + let result = response.payload.data + console.log('login result:', result) if (result) { if (0 !== result.code) { - let str = ''; + let str = '' if (Array.isArray(result.messages)) { result.messages.map((item) => { - str = str + item + '\n'; + str = str + item + '\n' }) } - message.error('登录失败: \n'+ str); + message.error('登录失败: \n' + str) } else { - console.info('[Login] res.payload.data: ', result); - message.success('欢迎你,' + result.data.name); - this.props.history.replace('/'); + console.info('[Login] res.payload.data: ', result) + message.success('欢迎你,' + result.data.name) + this.props.history.replace('/') } } } }).catch(err => { - console.error('[Login] err: ', err); + console.error('[Login] err: ', err) this.setState({ loading: false - }); - }); + }) + }) this.props.form.validateFields((err, values) => { if (!err) { - console.info('提交表单信息', values); + console.info('提交表单信息', values) } else { - console.error(err); + console.error(err) } - }); + }) } render() { - const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched, setFieldsValue } = this.props.form; + const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched, setFieldsValue } = this.props.form // Only show error after a field is touched. - const userNameError = isFieldTouched('userName') && getFieldError('userName'); - const passwordError = isFieldTouched('password') && getFieldError('password'); + const userNameError = isFieldTouched('userName') && getFieldError('userName') + const passwordError = isFieldTouched('password') && getFieldError('password') return ( @@ -110,11 +111,11 @@ class Login extends React.Component { {getFieldDecorator('user', { - rules: [{ required: true, message: 'Please input your username!' }], + rules: [{ required: true, message: 'Please input your username!' }] })( } + prefix={} ref={node => this.userNameInput = node} placeholder="admin" /> @@ -123,12 +124,12 @@ class Login extends React.Component { {getFieldDecorator('password', { - rules: [{ required: true, message: 'Please input your password!' }], + rules: [{ required: true, message: 'Please input your password!' }] })( } + prefix={} type='password' - placeholder='123456' /> + placeholder='123456'/> )}

@@ -144,17 +145,17 @@ class Login extends React.Component { } } -Login.propTypes = propTypes; +Login.propTypes = propTypes -Login = Form.create()(Login); +Login = Form.create()(Login) function mapStateToProps(state) { - const { auth } = state; + const { auth } = state if (auth.user) { - return { user: auth.user, loggingIn: auth.loggingIn, message: '' }; + return { user: auth.user, loggingIn: auth.loggingIn, message: '' } } - return { user: null, loggingIn: auth.loggingIn, message: auth.message }; + return { user: null, loggingIn: auth.loggingIn, message: auth.message } } function mapDispatchToProps(dispatch) { diff --git a/demos/reactapp/src/views/pages/login/Login.less b/demos/reactapp/src/views/pages/login/Login.less index ddcea93..b399128 100644 --- a/demos/reactapp/src/views/pages/login/Login.less +++ b/demos/reactapp/src/views/pages/login/Login.less @@ -7,6 +7,7 @@ .login-form { background: #F3F9F9; border-radius: 18px; + .input { width: 300px; size: 18px; @@ -17,13 +18,16 @@ transition: color 0.3s; font-size: 12px; } + .anticon-close-circle:hover { color: #999; } + .anticon-close-circle:active { color: #666; } } + .btn-login { width: 300px; } diff --git a/demos/reactapp/src/views/pages/mail/Mailbox.jsx b/demos/reactapp/src/views/pages/mail/Mailbox.jsx index 91b16d3..afa42ad 100644 --- a/demos/reactapp/src/views/pages/mail/Mailbox.jsx +++ b/demos/reactapp/src/views/pages/mail/Mailbox.jsx @@ -1,49 +1,49 @@ -import { Table } from 'antd'; -import React from 'react'; +import { Table } from 'antd' +import React from 'react' const columns = [{ title: 'Name', - dataIndex: 'name', + dataIndex: 'name' }, { title: 'Age', - dataIndex: 'age', + dataIndex: 'age' }, { title: 'Address', - dataIndex: 'address', -}]; + dataIndex: 'address' +}] const data = [{ key: '1', name: 'John Brown', age: 32, - address: 'New York No. 1 Lake Park', + address: 'New York No. 1 Lake Park' }, { key: '2', name: 'Jim Green', age: 42, - address: 'London No. 1 Lake Park', + address: 'London No. 1 Lake Park' }, { key: '3', name: 'Joe Black', age: 32, - address: 'Sidney No. 1 Lake Park', + address: 'Sidney No. 1 Lake Park' }, { key: '4', name: 'Joe Black', age: 32, - address: 'Sidney No. 1 Lake Park', + address: 'Sidney No. 1 Lake Park' }, { key: '5', name: 'Joe Black', age: 32, - address: 'Sidney No. 1 Lake Park', -}]; + address: 'Sidney No. 1 Lake Park' +}] export default class MailboxPage extends React.Component { render() { return (

- +
- ); + ) } } diff --git a/demos/reactapp/src/views/pages/user/User.jsx b/demos/reactapp/src/views/pages/user/User.jsx index ea1f394..00eb5c9 100644 --- a/demos/reactapp/src/views/pages/user/User.jsx +++ b/demos/reactapp/src/views/pages/user/User.jsx @@ -1,75 +1,76 @@ -import React, {PropTypes} from "react"; -import {Alert, Button, Col, Input, Row, Select, Table} from "antd"; -import "./User.less"; -const {Option, OptGroup} = Select; +import React from 'react' +import { Alert, Button, Col, Input, Row, Select, Table } from 'antd' +import './User.less' + +const { Option, OptGroup } = Select const columns = [{ title: 'Name', dataIndex: 'name', filters: [{ text: 'Joe', - value: 'Joe', + value: 'Joe' }, { text: 'Jim', - value: 'Jim', + value: 'Jim' }, { text: 'Submenu', value: 'Submenu', children: [{ text: 'Green', - value: 'Green', + value: 'Green' }, { text: 'Black', - value: 'Black', - }], + value: 'Black' + }] }], // specify the condition of filtering result // here is that finding the name started with `value` onFilter: (value, record) => record.name.indexOf(value) === 0, - sorter: (a, b) => a.name.length - b.name.length, + sorter: (a, b) => a.name.length - b.name.length }, { title: 'Age', dataIndex: 'age', - sorter: (a, b) => a.age - b.age, + sorter: (a, b) => a.age - b.age }, { title: 'Address', dataIndex: 'address', filters: [{ text: 'London', - value: 'London', + value: 'London' }, { text: 'New York', - value: 'New York', + value: 'New York' }], filterMultiple: false, onFilter: (value, record) => record.address.indexOf(value) === 0, - sorter: (a, b) => a.address.length - b.address.length, -}]; + sorter: (a, b) => a.address.length - b.address.length +}] const data = [{ key: '1', name: 'John Brown', age: 32, - address: 'New York No. 1 Lake Park', + address: 'New York No. 1 Lake Park' }, { key: '2', name: 'Jim Green', age: 42, - address: 'London No. 1 Lake Park', + address: 'London No. 1 Lake Park' }, { key: '3', name: 'Joe Black', age: 32, - address: 'Sidney No. 1 Lake Park', + address: 'Sidney No. 1 Lake Park' }, { key: '4', name: 'Jim Red', age: 32, - address: 'London No. 2 Lake Park', -}]; + address: 'London No. 2 Lake Park' +}] function onChange(pagination, filters, sorter) { - console.log('params', pagination, filters, sorter); + console.log('params', pagination, filters, sorter) } export default class UserView extends React.Component { @@ -86,7 +87,7 @@ export default class UserView extends React.Component { @@ -138,6 +139,6 @@ export default class UserView extends React.Component {
- ); + ) } } diff --git a/demos/reactapp/src/views/pages/user/User.less b/demos/reactapp/src/views/pages/user/User.less index 8cb0e80..1cff55b 100644 --- a/demos/reactapp/src/views/pages/user/User.less +++ b/demos/reactapp/src/views/pages/user/User.less @@ -1,3 +1,3 @@ .user-view-row { - padding-bottom: 15px; + padding-bottom: 15px; } diff --git a/demos/reactapp/src/webapi/mock/index.js b/demos/reactapp/src/webapi/mock/index.js index e49c73b..87efa81 100644 --- a/demos/reactapp/src/webapi/mock/index.js +++ b/demos/reactapp/src/webapi/mock/index.js @@ -1,22 +1,22 @@ -const axios = require('axios'); -const MockAdapter = require('axios-mock-adapter'); -const mockAxios = axios.create(); +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') +const mockAxios = axios.create() // mock 数据 -const mock = new MockAdapter(mockAxios); +const mock = new MockAdapter(mockAxios) mock.onPut('/login').reply(config => { - let postData = JSON.parse(config.data); - console.info('[mock]', postData); + let postData = JSON.parse(config.data) + console.info('[mock]', postData) if (postData.username === 'admin' && postData.password === '123456') { - let result = require('./user'); - console.info('[mock result]', result); - return [200, result]; + let result = require('./user') + console.info('[mock result]', result) + return [200, result] } else { - return [500, { message: "Incorrect user or password" }]; + return [500, { message: 'Incorrect user or password' }] } -}); -mock.onGet('/logout').reply(200, {}); -mock.onGet('/my').reply(200, require('./user')); -mock.onGet('/menu').reply(200, require('./menu')); +}) +mock.onGet('/logout').reply(200, {}) +mock.onGet('/my').reply(200, require('./user')) +mock.onGet('/menu').reply(200, require('./menu')) -export default mockAxios; +export default mockAxios diff --git a/demos/reactapp/src/webapi/mock/menu.js b/demos/reactapp/src/webapi/mock/menu.js index 1284087..a6d09a0 100644 --- a/demos/reactapp/src/webapi/mock/menu.js +++ b/demos/reactapp/src/webapi/mock/menu.js @@ -1,92 +1,92 @@ module.exports = { - "code": 0, - "messages": [ - "成功" + 'code': 0, + 'messages': [ + '成功' ], - "data": [ + 'data': [ { - "key": 0, - "title": "Home", - "icon": "home", - "type": "Item", - "url": "/pages/home", - "children": [] + 'key': 0, + 'title': 'Home', + 'icon': 'home', + 'type': 'Item', + 'url': '/pages/home', + 'children': [] }, { - "key": 1, - "title": "Pages", - "icon": "user", - "type": "SubMenu", - "url": null, - "children": [ + 'key': 1, + 'title': 'Pages', + 'icon': 'user', + 'type': 'SubMenu', + 'url': null, + 'children': [ { - "key": 11, - "title": "Mailbox", - "icon": "mail", - "type": "Item", - "url": "/pages/mailbox", - "children": [] + 'key': 11, + 'title': 'Mailbox', + 'icon': 'mail', + 'type': 'Item', + 'url': '/pages/mailbox', + 'children': [] }, { - "key": 12, - "title": "User", - "icon": "user", - "type": "Item", - "url": "/pages/user", - "children": [] + 'key': 12, + 'title': 'User', + 'icon': 'user', + 'type': 'Item', + 'url': '/pages/user', + 'children': [] } ] }, { - "key": 2, - "title": "Others", - "icon": "coffee", - "type": "SubMenu", - "url": null, - "children": [ + 'key': 2, + 'title': 'Others', + 'icon': 'coffee', + 'type': 'SubMenu', + 'url': null, + 'children': [ { - "key": 21, - "title": "Group1", - "icon": "windows-o", - "type": "ItemGroup", - "url": null, - "children": [ + 'key': 21, + 'title': 'Group1', + 'icon': 'windows-o', + 'type': 'ItemGroup', + 'url': null, + 'children': [ { - "key": 22, - "title": "Group1-1", - "icon": null, - "type": "Item", - "url": "/pages/home", - "children": [] + 'key': 22, + 'title': 'Group1-1', + 'icon': null, + 'type': 'Item', + 'url': '/pages/home', + 'children': [] } ] }, { - "key": 23, - "title": "Divider", - "icon": null, - "type": "Divider", - "url": null, - "children": [] + 'key': 23, + 'title': 'Divider', + 'icon': null, + 'type': 'Divider', + 'url': null, + 'children': [] }, { - "key": 24, - "title": "Group2", - "icon": "apple-o", - "type": "ItemGroup", - "url": null, - "children": [ + 'key': 24, + 'title': 'Group2', + 'icon': 'apple-o', + 'type': 'ItemGroup', + 'url': null, + 'children': [ { - "key": 25, - "title": "Group2-1", - "icon": null, - "type": "Item", - "url": "/pages/home", - "children": [] + 'key': 25, + 'title': 'Group2-1', + 'icon': null, + 'type': 'Item', + 'url': '/pages/home', + 'children': [] } ] } ] } ] -}; +} diff --git a/demos/reactapp/src/webapi/mock/user.js b/demos/reactapp/src/webapi/mock/user.js index 5869131..2c12895 100644 --- a/demos/reactapp/src/webapi/mock/user.js +++ b/demos/reactapp/src/webapi/mock/user.js @@ -1,5 +1,5 @@ module.exports = { code: 0, - messages: ["成功"], - data: { uid: "1", role: "ADMIN", name: "admin" } -}; + messages: ['成功'], + data: { uid: '1', role: 'ADMIN', name: 'admin' } +} diff --git a/demos/reactapp/src/webapi/webapi.js b/demos/reactapp/src/webapi/webapi.js index 9382b94..ef2d117 100644 --- a/demos/reactapp/src/webapi/webapi.js +++ b/demos/reactapp/src/webapi/webapi.js @@ -1,5 +1,5 @@ if (process.env.NODE_ENV === 'development') { - module.exports = require('./mock').default; + module.exports = require('./mock').default } else { - module.exports = require('../utils/http').default; + module.exports = require('../utils/http').default } diff --git a/docs/index.html b/docs/index.html index eb3900d..ec2f567 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,250 +1,250 @@ - - - Nginx Tutorial - - - - - - + + + - + + +
正在加载...
+ + + + + - .cover-main blockquote p { - color: #5c5869; - font-family: "Arial", 隶书, serif; - } - - .cover-main ul a:hover { - color: #fe4165 !important; - } - - .cover-main p a:hover { - text-align: center; - background-image: -webkit-linear-gradient(left, #ffdcb4, #b96972 25%, #e88a57 50%, #804170 75%, #a596cd); - -webkit-text-fill-color: transparent; - -webkit-background-clip: text; - -webkit-background-size: 200% 100%; - -webkit-animation: masked-animation 1.5s infinite linear; - } - - /* content 样式内容 */ - .sidebar a, - .content a { - color: #399ab2 !important; - text-decoration: none !important; - } - - .sidebar a:hover, - .content a:hover { - color: #fe4165 !important; - text-decoration: underline !important; - } - - .content h1 :hover, - .content h2 :hover, - .content h3 :hover, - .content h4 :hover { - text-align: center; - background-image: -webkit-linear-gradient(left, #ffdcb4, #b96972 25%, #e88a57 50%, #804170 75%, #a596cd); - -webkit-text-fill-color: transparent; - -webkit-background-clip: text; - -webkit-background-size: 200% 100%; - -webkit-animation: masked-animation 1.5s infinite linear; - font-family: "微软雅黑", serif; - font-weight: bold; - } - - @-webkit-keyframes masked-animation { - 0% { - background-position: 0 0; - } - 100% { - background-position: -100% 0; - } - } - - /*.cover-main {*/ - /*text-shadow: 2px 2px 5px grey;*/ - /*}*/ - - .content h1 a, - .content h1 span { - color: #399ab2 !important; - font-size: 30px; - text-shadow: 2px 2px 5px grey; - } - - .content h2 a, - .content h2 span { - color: #60497c !important; - font-size: 26px; - text-shadow: 2px 2px 5px grey; - } - - .content h3 a, - .content h3 span { - color: #346093 !important; - font-size: 22px; - text-shadow: 2px 2px 5px grey; - } - - .content h4 a, - .content h4 span { - font-size: 18px; - color: #78943a; - text-shadow: 2px 2px 5px grey; - } - - img.emoji { - border: none; - border-radius: 0; - box-shadow: none; - } - - - - - -
正在加载...
- - - - - - - - - - - - - + + + + + + +