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
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 (
-
- );
+ < 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 @@
-