Browse Source

首次提交

wuweihao 3 years ago
parent
commit
4e843e877d
36 changed files with 2340 additions and 0 deletions
  1. 9 0
      src/main/java/com/fourdage/base/common/Constats.java
  2. 46 0
      src/main/java/com/fourdage/base/common/DateEditor.java
  3. 567 0
      src/main/java/com/fourdage/base/common/HttpHelper.java
  4. 118 0
      src/main/java/com/fourdage/base/common/JsonResult.java
  5. 112 0
      src/main/java/com/fourdage/base/common/utils/AESUtils.java
  6. 47 0
      src/main/java/com/fourdage/base/common/utils/MD5Utils.java
  7. 7 0
      src/main/java/com/fourdage/base/common/utils/Util.java
  8. 33 0
      src/main/java/com/fourdage/base/config/CacheConfig.java
  9. 24 0
      src/main/java/com/fourdage/base/config/FreeMarkerConfig.java
  10. 89 0
      src/main/java/com/fourdage/base/config/WebMvcConfig.java
  11. 34 0
      src/main/java/com/fourdage/base/config/interceptor/CommonInterceptor.java
  12. 97 0
      src/main/java/com/fourdage/base/config/shiro/MyRealm.java
  13. 96 0
      src/main/java/com/fourdage/base/config/shiro/ShiroConfig.java
  14. 54 0
      src/main/java/com/fourdage/base/config/shiro/ShiroManager.java
  15. 44 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/AuthenticatedTag.java
  16. 42 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/GuestTag.java
  17. 51 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/HasAnyRolesTag.java
  18. 12 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/HasPermissionTag.java
  19. 10 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/HasRoleTag.java
  20. 10 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/LacksPermissionTag.java
  21. 11 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/LacksRoleTag.java
  22. 32 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/NotAuthenticatedTag.java
  23. 43 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/PermissionTag.java
  24. 119 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/PrincipalTag.java
  25. 27 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/RoleTag.java
  26. 44 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/SecureTag.java
  27. 23 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/ShiroTags.java
  28. 37 0
      src/main/java/com/fourdage/base/config/shiro/freemarker/UserTag.java
  29. 13 0
      src/main/java/com/fourdage/base/controller/AdminIndexController.java
  30. 118 0
      src/main/java/com/fourdage/base/controller/BaseController.java
  31. 100 0
      src/main/java/com/fourdage/base/controller/LoginController.java
  32. 15 0
      src/main/java/com/fourdage/base/dao/IBaseDao.java
  33. 15 0
      src/main/java/com/fourdage/base/entity/BaseEntity.java
  34. 45 0
      src/main/java/com/fourdage/base/service/IBaseService.java
  35. 120 0
      src/main/java/com/fourdage/base/service/impl/BaseServiceImpl.java
  36. 76 0
      src/main/java/com/fourdage/base/vo/ZtreeView.java

+ 9 - 0
src/main/java/com/fourdage/base/common/Constats.java

@@ -0,0 +1,9 @@
+package com.fourdage.base.common;
+
+public interface Constats {
+
+    public static final String CURRENTUSER = "_currentUser";
+
+    public static final String RESOURCECACHENAME = "resourceCache";
+
+}

+ 46 - 0
src/main/java/com/fourdage/base/common/DateEditor.java

@@ -0,0 +1,46 @@
+package com.fourdage.base.common;
+
+import java.beans.PropertyEditorSupport;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.lang3.time.DateUtils;
+
+public class DateEditor extends PropertyEditorSupport {
+
+    private boolean emptyAsNull;
+    private String dateFormat = "yyyy-MM-dd HH:mm:ss";
+    public static final String[] DATE_PATTERNS = {"yyyy", "yyyy-MM", "yyyyMM", "yyyy/MM", "yyyy-MM-dd", "yyyyMMdd",
+            "yyyy/MM/dd", "yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss", "yyyy/MM/dd HH:mm:ss"};
+
+    public DateEditor(boolean emptyAsNull) {
+        this.emptyAsNull = emptyAsNull;
+    }
+
+    public DateEditor(boolean emptyAsNull, String dateFormat) {
+        this.emptyAsNull = emptyAsNull;
+        this.dateFormat = dateFormat;
+    }
+
+    public String getAsText() {
+        Date date = (Date) getValue();
+        return date != null ? new SimpleDateFormat(this.dateFormat).format(date) : "";
+    }
+
+    public void setAsText(String text) {
+        if (text == null) {
+            setValue(null);
+        } else {
+            String str = text.trim();
+            if ((this.emptyAsNull) && ("".equals(str)))
+                setValue(null);
+            else
+                try {
+                    setValue(DateUtils.parseDate(str, DATE_PATTERNS));
+                } catch (ParseException e) {
+                    setValue(null);
+                }
+        }
+    }
+}

+ 567 - 0
src/main/java/com/fourdage/base/common/HttpHelper.java

@@ -0,0 +1,567 @@
+package com.fourdage.base.common;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.Socket;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+
+public class HttpHelper {
+	
+	/**
+     * POST请求
+     *
+     * @param urlStr 请求地址
+     * @param params 参数字典      
+     * @param charset 编码,最好传“UTF-8”   
+     * @return   
+     * @exception  RuntimeException  
+     */
+    public static String sendPostByHttpUrlConnection(String urlStr, Map<String, Object> params, String charset) {
+        StringBuffer resultBuffer = null;
+        // 构建请求参数
+        String sbParams= JoiningTogetherParams(params);
+        HttpURLConnection con = null;
+        OutputStreamWriter osw = null;
+        BufferedReader br = null;
+        // 发送请求
+        try {
+            URL url = new URL(urlStr);
+            con = (HttpURLConnection) url.openConnection();
+            con.setRequestMethod("POST");
+            con.setDoOutput(true);
+            con.setDoInput(true);
+            con.setUseCaches(false);
+            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            if (sbParams != null && sbParams.length() > 0) {
+                osw = new OutputStreamWriter(con.getOutputStream(), charset);
+                osw.write(sbParams);
+                osw.flush();
+            }
+            // 读取返回内容
+            resultBuffer = new StringBuffer();
+            int contentLength = Integer.parseInt(con.getHeaderField("Content-Length"));
+            if (contentLength > 0) {
+                br = new BufferedReader(new InputStreamReader(con.getInputStream(), charset));
+                String temp;
+                while ((temp = br.readLine()) != null) {
+                    resultBuffer.append(temp);
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (osw != null) {
+                try {
+                    osw.close();
+                } catch (IOException e) {
+                    osw = null;
+                    throw new RuntimeException(e);
+                } finally {
+                    if (con != null) {
+                        con.disconnect();
+                        con = null;
+                    }
+                }
+            }
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    br = null;
+                    throw new RuntimeException(e);
+                } finally {
+                    if (con != null) {
+                        con.disconnect();
+                        con = null;
+                    }
+                }
+            }
+        }
+
+        return resultBuffer.toString();
+    }
+
+
+    public static String sendPostByUrlConnection(String urlStr, Map<String, Object> params, String charset) {
+        StringBuffer resultBuffer = null;
+        // 构建请求参数
+        String sbParams= JoiningTogetherParams(params);
+        URLConnection con = null;
+        OutputStreamWriter osw = null;
+        BufferedReader br = null;
+        try {
+            URL realUrl = new URL(urlStr);
+            // 打开和URL之间的连接
+            con = realUrl.openConnection();
+            // 设置通用的请求属性
+            con.setRequestProperty("accept", "*/*");
+            con.setRequestProperty("connection", "Keep-Alive");
+            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            con.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+            // 发送POST请求必须设置如下两行
+            con.setDoOutput(true);
+            con.setDoInput(true);
+            // 获取URLConnection对象对应的输出流
+            osw = new OutputStreamWriter(con.getOutputStream(), charset);
+            if (sbParams != null && sbParams.length() > 0) {
+                // 发送请求参数
+                osw.write(sbParams);
+                // flush输出流的缓冲
+                osw.flush();
+            }
+            // 定义BufferedReader输入流来读取URL的响应
+            resultBuffer = new StringBuffer();
+            int contentLength = Integer.parseInt(con.getHeaderField("Content-Length"));
+            if (contentLength > 0) {
+                br = new BufferedReader(new InputStreamReader(con.getInputStream(), charset));
+                String temp;
+                while ((temp = br.readLine()) != null) {
+                    resultBuffer.append(temp);
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (osw != null) {
+                try {
+                    osw.close();
+                } catch (IOException e) {
+                    osw = null;
+                    throw new RuntimeException(e);
+                }
+            }
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    br = null;
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+        return resultBuffer.toString();
+    }
+
+
+    public static String sendGetByHttpUrlConnection(String urlStr, Map<String, Object> params, String charset) {
+        StringBuffer resultBuffer = null;
+        // 构建请求参数
+        String sbParams= JoiningTogetherParams(params);
+        HttpURLConnection con = null;
+        BufferedReader br = null;
+        try {
+            URL url = null;
+            if (sbParams != null && sbParams.length() > 0) {
+                url = new URL(urlStr + "?" + sbParams);
+            } else {
+                url = new URL(urlStr);
+            }
+            con = (HttpURLConnection) url.openConnection();
+            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            con.connect();
+            resultBuffer = new StringBuffer();
+            br = new BufferedReader(new InputStreamReader(con.getInputStream(), charset));
+            String temp;
+            while ((temp = br.readLine()) != null) {
+                resultBuffer.append(temp);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    br = null;
+                    throw new RuntimeException(e);
+                } finally {
+                    if (con != null) {
+                        con.disconnect();
+                        con = null;
+                    }
+                }
+            }
+        }
+        return resultBuffer.toString();
+    }
+
+
+    public static String sendGetByUrlConnection(String urlStr, Map<String, Object> params, String charset) {
+        StringBuffer resultBuffer = null;
+        // 构建请求参数
+        String sbParams= JoiningTogetherParams(params);
+        BufferedReader br = null;
+        try {
+            URL url = null;
+            if (sbParams != null && sbParams.length() > 0) {
+                url = new URL(urlStr + "?" + sbParams);
+            } else {
+                url = new URL(urlStr);
+            }
+            URLConnection con = url.openConnection();
+            // 设置请求属性
+            con.setRequestProperty("accept", "*/*");
+            con.setRequestProperty("connection", "Keep-Alive");
+            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            con.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+            // 建立连接
+            con.connect();
+            resultBuffer = new StringBuffer();
+            br = new BufferedReader(new InputStreamReader(con.getInputStream(), charset));
+            String temp;
+            while ((temp = br.readLine()) != null) {
+                resultBuffer.append(temp);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    br = null;
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+        return resultBuffer.toString();
+    }
+
+
+    public static String httpClientPost(String urlStr, Map<String, Object> params, String charset) {
+        StringBuffer resultBuffer = null;
+        HttpClient client = new DefaultHttpClient();
+        HttpPost httpPost = new HttpPost(urlStr);
+        // 构建请求参数
+        List<NameValuePair> list = new ArrayList<NameValuePair>();
+        Iterator<Entry<String, Object>> iterator = params.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Entry<String, Object> elem = iterator.next();
+            list.add(new BasicNameValuePair(elem.getKey(), String.valueOf(elem.getValue())));
+        }
+        BufferedReader br = null;
+        try {
+            if (list.size() > 0) {
+                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, charset);
+                httpPost.setEntity(entity);
+            }
+            HttpResponse response = client.execute(httpPost);
+            // 读取服务器响应数据
+            resultBuffer = new StringBuffer();
+            br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+            String temp;
+            while ((temp = br.readLine()) != null) {
+                resultBuffer.append(temp);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    br = null;
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+        return resultBuffer.toString();
+    }
+
+
+    public static String httpClientGet(String urlStr, Map<String, Object> params, String charset) {
+        StringBuffer resultBuffer = null;
+        HttpClient client = new DefaultHttpClient();
+        BufferedReader br = null;
+        // 构建请求参数
+        StringBuffer sbParams = new StringBuffer();
+        if (params != null && params.size() > 0) {
+            for (Entry<String, Object> entry : params.entrySet()) {
+                sbParams.append(entry.getKey());
+                sbParams.append("=");
+                try {
+                    sbParams.append(URLEncoder.encode(String.valueOf(entry.getValue()), charset));
+                } catch (UnsupportedEncodingException e) {
+                    throw new RuntimeException(e);
+                }
+                sbParams.append("&");
+            }
+        }
+        if (sbParams != null && sbParams.length() > 0) {
+            urlStr = urlStr + "?" + sbParams.substring(0, sbParams.length() - 1);
+        }
+        HttpGet httpGet = new HttpGet(urlStr);
+        try {
+            HttpResponse response = client.execute(httpGet);
+            // 读取服务器响应数据
+            br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+            String temp;
+            resultBuffer = new StringBuffer();
+            while ((temp = br.readLine()) != null) {
+                resultBuffer.append(temp);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    br = null;
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+        return resultBuffer.toString();
+    }
+
+    public static String sendSocketPost(String urlStr, Map<String, Object> params, String charset) {
+        String result = "";
+        // 构建请求参数
+        StringBuffer sbParams = new StringBuffer();
+        if (params != null && params.size() > 0) {
+            for (Entry<String, Object> entry : params.entrySet()) {
+                sbParams.append(entry.getKey());
+                sbParams.append("=");
+                sbParams.append(entry.getValue());
+                sbParams.append("&");
+            }
+        }
+        Socket socket = null;
+        OutputStreamWriter osw = null;
+        InputStream is = null;
+        try {
+            URL url = new URL(urlStr);
+            String host = url.getHost();
+            int port = url.getPort();
+            if (-1 == port) {
+                port = 80;
+            }
+            String path = url.getPath();
+            socket = new Socket(host, port);
+            StringBuffer sb = new StringBuffer();
+            sb.append("POST " + path + " HTTP/1.1\r\n");
+            sb.append("Host: " + host + "\r\n");
+            sb.append("Connection: Keep-Alive\r\n");
+            sb.append("Content-Type: application/x-www-form-urlencoded; charset=utf-8 \r\n");
+            sb.append("Content-Length: ").append(sb.toString().getBytes().length).append("\r\n");
+            // 这里一个回车换行,表示消息头写完,不然服务器会继续等待
+            sb.append("\r\n");
+            if (sbParams != null && sbParams.length() > 0) {
+                sb.append(sbParams.substring(0, sbParams.length() - 1));
+            }
+            osw = new OutputStreamWriter(socket.getOutputStream());
+            osw.write(sb.toString());
+            osw.flush();
+            is = socket.getInputStream();
+            String line = null;
+            // 服务器响应体数据长度
+            int contentLength = 0;
+            // 读取http响应头部信息
+            do {
+                line = readLine(is, 0, charset);
+                if (line.startsWith("Content-Length")) {
+                    // 拿到响应体内容长度
+                    contentLength = Integer.parseInt(line.split(":")[1].trim());
+                }
+                // 如果遇到了一个单独的回车换行,则表示请求头结束
+            } while (!line.equals("\r\n"));
+            // 读取出响应体数据(就是你要的数据)
+            result = readLine(is, contentLength, charset);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (osw != null) {
+                try {
+                    osw.close();
+                } catch (IOException e) {
+                    osw = null;
+                    throw new RuntimeException(e);
+                } finally {
+                    if (socket != null) {
+                        try {
+                            socket.close();
+                        } catch (IOException e) {
+                            socket = null;
+                            throw new RuntimeException(e);
+                        }
+                    }
+                }
+            }
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    is = null;
+                    throw new RuntimeException(e);
+                } finally {
+                    if (socket != null) {
+                        try {
+                            socket.close();
+                        } catch (IOException e) {
+                            socket = null;
+                            throw new RuntimeException(e);
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    public static String sendSocketGet(String urlStr, Map<String, Object> params, String charset) {
+        String result = "";
+        // 构建请求参数
+        StringBuffer sbParams = new StringBuffer();
+        if (params != null && params.size() > 0) {
+            for (Entry<String, Object> entry : params.entrySet()) {
+                sbParams.append(entry.getKey());
+                sbParams.append("=");
+                sbParams.append(entry.getValue());
+                sbParams.append("&");
+            }
+        }
+        Socket socket = null;
+        OutputStreamWriter osw = null;
+        InputStream is = null;
+        try {
+            URL url = new URL(urlStr);
+            String host = url.getHost();
+            int port = url.getPort();
+            if (-1 == port) {
+                port = 80;
+            }
+            String path = url.getPath();
+            socket = new Socket(host, port);
+            StringBuffer sb = new StringBuffer();
+            sb.append("GET " + path + " HTTP/1.1\r\n");
+            sb.append("Host: " + host + "\r\n");
+            sb.append("Connection: Keep-Alive\r\n");
+            sb.append("Content-Type: application/x-www-form-urlencoded; charset=utf-8 \r\n");
+            sb.append("Content-Length: ").append(sb.toString().getBytes().length).append("\r\n");
+            // 这里一个回车换行,表示消息头写完,不然服务器会继续等待
+            sb.append("\r\n");
+            if (sbParams != null && sbParams.length() > 0) {
+                sb.append(sbParams.substring(0, sbParams.length() - 1));
+            }
+            osw = new OutputStreamWriter(socket.getOutputStream());
+            osw.write(sb.toString());
+            osw.flush();
+            is = socket.getInputStream();
+            String line = null;
+            // 服务器响应体数据长度
+            int contentLength = 0;
+            // 读取http响应头部信息
+            do {
+                line = readLine(is, 0, charset);
+                if (line.startsWith("Content-Length")) {
+                    // 拿到响应体内容长度
+                    contentLength = Integer.parseInt(line.split(":")[1].trim());
+                }
+                // 如果遇到了一个单独的回车换行,则表示请求头结束
+            } while (!line.equals("\r\n"));
+            // 读取出响应体数据(就是你要的数据)
+            result = readLine(is, contentLength, charset);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (osw != null) {
+                try {
+                    osw.close();
+                } catch (IOException e) {
+                    osw = null;
+                    throw new RuntimeException(e);
+                } finally {
+                    if (socket != null) {
+                        try {
+                            socket.close();
+                        } catch (IOException e) {
+                            socket = null;
+                            throw new RuntimeException(e);
+                        }
+                    }
+                }
+            }
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    is = null;
+                    throw new RuntimeException(e);
+                } finally {
+                    if (socket != null) {
+                        try {
+                            socket.close();
+                        } catch (IOException e) {
+                            socket = null;
+                            throw new RuntimeException(e);
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+
+    private static String readLine(InputStream is, int contentLength, String charset) throws IOException {
+        List<Byte> lineByte = new ArrayList<Byte>();
+        byte tempByte;
+        int cumsum = 0;
+        if (contentLength != 0) {
+            do {
+                tempByte = (byte) is.read();
+                lineByte.add(Byte.valueOf(tempByte));
+                cumsum++;
+            } while (cumsum < contentLength);// cumsum等于contentLength表示已读完
+        } else {
+            do {
+                tempByte = (byte) is.read();
+                lineByte.add(Byte.valueOf(tempByte));
+            } while (tempByte != 10);// 换行符的ascii码值为10
+        }
+
+        byte[] resutlBytes = new byte[lineByte.size()];
+        for (int i = 0; i < lineByte.size(); i++) {
+            resutlBytes[i] = (lineByte.get(i)).byteValue();
+        }
+        return new String(resutlBytes, charset);
+    }
+    
+    private static String JoiningTogetherParams(Map<String, Object> params){
+        StringBuffer sbParams = new StringBuffer();
+        if (params != null && params.size() > 0) {
+            for (Entry<String, Object> e : params.entrySet()) {
+                sbParams.append(e.getKey());
+                sbParams.append("=");
+                sbParams.append(e.getValue());
+                sbParams.append("&");
+            }
+            return sbParams.substring(0, sbParams.length() - 1);
+        }
+        return "";
+    }
+
+}
+

+ 118 - 0
src/main/java/com/fourdage/base/common/JsonResult.java

@@ -0,0 +1,118 @@
+package com.fourdage.base.common;
+
+import java.io.Serializable;
+
+/**
+ * Json 统一返回消息类
+ *
+ * @author SPPan
+ */
+public class JsonResult implements Serializable {
+    private static final long serialVersionUID = -1491499610244557029L;
+    public static int CODE_SUCCESS = 0;
+    public static int CODE_FAILURED = -1;
+    public static String[] NOOP = new String[]{};
+
+    private int code; // 处理状态:0: 成功
+    private String message;
+    private Object data; // 返回数据
+
+    private JsonResult(int code, String message, Object data) {
+        this.code = code;
+        this.message = message;
+        this.data = data;
+    }
+
+    /**
+     * 处理成功,并返回数据
+     *
+     * @param data 数据对象
+     * @return data
+     */
+    public static final JsonResult success(Object data) {
+        return new JsonResult(CODE_SUCCESS, "操作成功", data);
+    }
+
+    /**
+     * 处理成功
+     *
+     * @return data
+     */
+    public static final JsonResult success() {
+        return new JsonResult(CODE_SUCCESS, "操作成功", NOOP);
+    }
+
+    /**
+     * 处理成功
+     *
+     * @param message 消息
+     * @return data
+     */
+    public static final JsonResult success(String message) {
+        return new JsonResult(CODE_SUCCESS, message, NOOP);
+    }
+
+    /**
+     * 处理成功
+     *
+     * @param message 消息
+     * @param data    数据对象
+     * @return data
+     */
+    public static final JsonResult success(String message, Object data) {
+        return new JsonResult(CODE_SUCCESS, message, data);
+    }
+
+    /**
+     * 处理失败,并返回数据(一般为错误信息)
+     *
+     * @param code    错误代码
+     * @param message 消息
+     * @return data
+     */
+    public static final JsonResult failure(int code, String message) {
+        return new JsonResult(code, message, NOOP);
+    }
+
+    /**
+     * 处理失败
+     *
+     * @param message 消息
+     * @return data
+     */
+    public static final JsonResult failure(String message) {
+        return failure(CODE_FAILURED, message);
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        return "JsonResult [code=" + code + ", message=" + message + ", data="
+                + data + "]";
+    }
+
+
+}

+ 112 - 0
src/main/java/com/fourdage/base/common/utils/AESUtils.java

@@ -0,0 +1,112 @@
+package com.fourdage.base.common.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * AES对称加密
+ */
+public class AESUtils {
+
+    private AESUtils() {
+    }
+
+    /**
+     * 加密
+     *
+     * @param secret 密钥
+     * @param value  待加密的字符串
+     * @return 加密后的字符串
+     */
+    public static String encrypt(String secret, String value) {
+        SecretKeySpec keySpec = getKey(secret);
+        IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());
+        try {
+            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
+            byte[] encrypted = cipher.doFinal(value.getBytes("UTF-8"));
+            return parseByte2HexStr(encrypted);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 解密
+     *
+     * @param secret 密钥
+     * @param value  待解密字符串
+     * @return 解密后的字符串
+     */
+    public static String decrypt(String secret, String value) {
+        SecretKeySpec keySpec = getKey(secret);
+        IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());
+        try {
+            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
+            byte[] encrypted1 = parseHexStr2Byte(value);
+            byte[] original = cipher.doFinal(encrypted1);
+            return new String(original, "UTF-8");
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 生成加密的密钥,保证长度为16位
+     *
+     * @param secret 用户的密钥
+     * @return 生成的密钥
+     */
+    private static SecretKeySpec getKey(String secret) {
+        byte[] bytes;
+        try {
+            bytes = secret.getBytes("UTF-8");
+            return new SecretKeySpec(Arrays.copyOf(bytes, 16), "AES");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 将二进制转换成16进制
+     *
+     * @param buf
+     * @return
+     */
+    public static String parseByte2HexStr(byte buf[]) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < buf.length; i++) {
+            String hex = Integer.toHexString(buf[i] & 0xFF);
+            if (hex.length() == 1) {
+                hex = '0' + hex;
+            }
+            sb.append(hex.toUpperCase());
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 将16进制转换为二进制
+     *
+     * @param hexStr
+     * @return
+     */
+    public static byte[] parseHexStr2Byte(String hexStr) {
+        if (hexStr.length() < 1)
+            return null;
+        byte[] result = new byte[hexStr.length() / 2];
+        for (int i = 0; i < hexStr.length() / 2; i++) {
+            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
+            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
+                    16);
+            result[i] = (byte) (high * 16 + low);
+        }
+        return result;
+    }
+}

+ 47 - 0
src/main/java/com/fourdage/base/common/utils/MD5Utils.java

@@ -0,0 +1,47 @@
+package com.fourdage.base.common.utils;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.springframework.util.StringUtils;
+
+
+public class MD5Utils {
+    /**
+     * 对字符串进行Md5加密
+     *
+     * @param input 原文
+     * @return md5后的密文
+     */
+    public static String md5(String input) {
+        byte[] code = null;
+        try {
+            code = MessageDigest.getInstance("md5").digest(input.getBytes());
+        } catch (NoSuchAlgorithmException e) {
+            code = input.getBytes();
+        }
+        BigInteger bi = new BigInteger(code);
+        return bi.abs().toString(32).toUpperCase();
+    }
+
+    /**
+     * 对字符串进行Md5加密
+     *
+     * @param input 原文
+     * @param salt  随机数
+     * @return string
+     */
+    public static String generatePasswordMD5(String input, String salt) {
+        if (StringUtils.isEmpty(salt)) {
+            salt = "";
+        }
+        return md5(salt + md5(input));
+    }
+
+    public static void main(String[] args) {
+        System.out.println(md5("111111"));
+        ;
+    }
+
+}

+ 7 - 0
src/main/java/com/fourdage/base/common/utils/Util.java

@@ -0,0 +1,7 @@
+package com.fourdage.base.common.utils;
+
+public class Util {
+	
+	public static final String USER_AGENT = "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";
+
+}

+ 33 - 0
src/main/java/com/fourdage/base/config/CacheConfig.java

@@ -0,0 +1,33 @@
+package com.fourdage.base.config;
+
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.ehcache.EhCacheCacheManager;
+import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.ClassPathResource;
+
+@Configuration
+//标注启动了缓存
+@EnableCaching
+public class CacheConfig {
+
+    /**
+     * ehcache 主要的管理器
+     */
+    @Bean
+    public EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean bean) {
+        return new EhCacheCacheManager(bean.getObject());
+    }
+
+    /**
+     * 据shared与否的设置,Spring分别通过CacheManager.create()或new CacheManager()方式来创建一个ehcache基地.
+     */
+    @Bean
+    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
+        EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean();
+        cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
+        cacheManagerFactoryBean.setShared(true);
+        return cacheManagerFactoryBean;
+    }
+}

+ 24 - 0
src/main/java/com/fourdage/base/config/FreeMarkerConfig.java

@@ -0,0 +1,24 @@
+package com.fourdage.base.config;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+
+import com.fourdage.base.config.shiro.freemarker.ShiroTags;
+
+@Configuration
+public class FreeMarkerConfig {
+
+    @Autowired
+    private freemarker.template.Configuration configuration;
+
+    @PostConstruct
+    public void setSharedVariable() {
+        try {
+            configuration.setSharedVariable("shiro", new ShiroTags());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 89 - 0
src/main/java/com/fourdage/base/config/WebMvcConfig.java

@@ -0,0 +1,89 @@
+package com.fourdage.base.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson.support.config.FastJsonConfig;
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4;
+import com.fourdage.base.config.interceptor.CommonInterceptor;
+
+@Configuration
+public class WebMvcConfig extends WebMvcConfigurerAdapter {
+    @Autowired
+    private CommonInterceptor commonInterceptor;
+
+    /**
+     * fastJson相关设置
+     */
+    private FastJsonConfig getFastJsonConfig() {
+
+        FastJsonConfig fastJsonConfig = new FastJsonConfig();
+        // 在serializerFeatureList中添加转换规则
+        List<SerializerFeature> serializerFeatureList = new ArrayList<SerializerFeature>();
+        serializerFeatureList.add(SerializerFeature.PrettyFormat);
+        serializerFeatureList.add(SerializerFeature.WriteMapNullValue);
+        serializerFeatureList.add(SerializerFeature.WriteNullStringAsEmpty);
+        serializerFeatureList.add(SerializerFeature.WriteNullListAsEmpty);
+        serializerFeatureList.add(SerializerFeature.DisableCircularReferenceDetect);
+        SerializerFeature[] serializerFeatures = serializerFeatureList.toArray(new SerializerFeature[serializerFeatureList.size()]);
+        fastJsonConfig.setSerializerFeatures(serializerFeatures);
+
+        return fastJsonConfig;
+    }
+
+    /**
+     * fastJson相关设置
+     */
+    private FastJsonHttpMessageConverter4 fastJsonHttpMessageConverter() {
+
+        FastJsonHttpMessageConverter4 fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter4();
+
+        List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
+        supportedMediaTypes.add(MediaType.parseMediaType("text/html;charset=UTF-8"));
+        supportedMediaTypes.add(MediaType.parseMediaType("application/json"));
+
+        fastJsonHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
+        fastJsonHttpMessageConverter.setFastJsonConfig(getFastJsonConfig());
+
+        return fastJsonHttpMessageConverter;
+    }
+
+    /**
+     * 添加fastJsonHttpMessageConverter到converters
+     */
+    @Override
+    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+        converters.add(fastJsonHttpMessageConverter());
+    }
+
+    /**
+     * 添加拦截器
+     */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(commonInterceptor).addPathPatterns("/**");
+        super.addInterceptors(registry);
+    }
+
+    @Bean
+    public FilterRegistrationBean registFilter() {
+        FilterRegistrationBean registration = new FilterRegistrationBean();
+        registration.setFilter(new OpenEntityManagerInViewFilter());
+        registration.addUrlPatterns("/*");
+        registration.setOrder(1);
+        return registration;
+    }
+
+
+}

+ 34 - 0
src/main/java/com/fourdage/base/config/interceptor/CommonInterceptor.java

@@ -0,0 +1,34 @@
+package com.fourdage.base.config.interceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+@Component
+public class CommonInterceptor implements HandlerInterceptor {
+
+    @Override
+    public boolean preHandle(HttpServletRequest request,
+                             HttpServletResponse response, Object handler) throws Exception {
+        return true;
+    }
+
+    @Override
+    public void postHandle(HttpServletRequest request,
+                           HttpServletResponse response, Object handler,
+                           ModelAndView modelAndView) throws Exception {
+        request.setAttribute("ctx", request.getContextPath());
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request,
+                                HttpServletResponse response, Object handler, Exception ex)
+            throws Exception {
+
+    }
+
+
+}

+ 97 - 0
src/main/java/com/fourdage/base/config/shiro/MyRealm.java

@@ -0,0 +1,97 @@
+package com.fourdage.base.config.shiro;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.IncorrectCredentialsException;
+import org.apache.shiro.authc.LockedAccountException;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authc.UnknownAccountException;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.realm.AuthorizingRealm;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.fourdage.base.common.utils.MD5Utils;
+import com.fourdage.system.entity.Resource;
+import com.fourdage.system.entity.Role;
+import com.fourdage.system.entity.User;
+import com.fourdage.system.service.IUserService;
+
+/**
+ * @author SPPan
+ */
+@Component
+public class MyRealm extends AuthorizingRealm {
+
+    public MyRealm() {
+        super(new AllowAllCredentialsMatcher());
+        setAuthenticationTokenClass(UsernamePasswordToken.class);
+
+        //FIXME: 暂时禁用Cache
+        setCachingEnabled(false);
+    }
+
+    @Autowired
+    private IUserService userService;
+
+    @Override
+    protected AuthorizationInfo doGetAuthorizationInfo(
+            PrincipalCollection principals) {
+        User user = (User) principals.getPrimaryPrincipal();
+        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
+        User dbUser = userService.findByUserName(user.getUserName());
+        Set<String> shiroPermissions = new HashSet<>();
+        Set<String> roleSet = new HashSet<String>();
+        Set<Role> roles = dbUser.getRoles();
+        for (Role role : roles) {
+            Set<Resource> resources = role.getResources();
+            for (Resource resource : resources) {
+                shiroPermissions.add(resource.getSourceKey());
+
+            }
+            roleSet.add(role.getRoleKey());
+        }
+        authorizationInfo.setRoles(roleSet);
+        authorizationInfo.setStringPermissions(shiroPermissions);
+        return authorizationInfo;
+    }
+
+    @Override
+    protected AuthenticationInfo doGetAuthenticationInfo(
+            AuthenticationToken token) throws AuthenticationException {
+        String username = (String) token.getPrincipal();
+
+        User user = userService.findByUserName(username);
+        // 账号不存在
+        if (user == null) {
+            throw new UnknownAccountException("账号或密码不正确");
+        }
+        Object credentials = token.getCredentials();
+        if (credentials == null) {
+            throw new UnknownAccountException("账号或密码不正确");
+        }
+        String password = new String((char[]) credentials);
+        // 密码错误
+        if (!MD5Utils.md5(password).equals(user.getPassword())) {
+            throw new IncorrectCredentialsException("账号或密码不正确");
+        }
+        // 账号锁定
+        if (user.getLocked() == 1) {
+            throw new LockedAccountException("账号已被锁定,请联系管理员");
+        }
+
+        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
+
+        return info;
+    }
+
+}

+ 96 - 0
src/main/java/com/fourdage/base/config/shiro/ShiroConfig.java

@@ -0,0 +1,96 @@
+package com.fourdage.base.config.shiro;
+
+import org.apache.shiro.cache.CacheManager;
+import org.apache.shiro.cache.MemoryConstrainedCacheManager;
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.context.annotation.Import;
+
+import com.fourdage.system.service.IResourceService;
+
+import javax.annotation.Resource;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+@Configuration
+@Import(ShiroManager.class)
+public class ShiroConfig {
+
+    @Resource
+    private IResourceService resourceService;
+
+
+    @Bean(name = "realm")
+    @DependsOn("lifecycleBeanPostProcessor")
+    @ConditionalOnMissingBean
+    public Realm realm() {
+        return new MyRealm();
+    }
+
+    /**
+     * 用户授权信息Cache
+     */
+    @Bean(name = "shiroCacheManager")
+    @ConditionalOnMissingBean
+    public CacheManager cacheManager() {
+        return new MemoryConstrainedCacheManager();
+    }
+
+    @Bean(name = "securityManager")
+    @ConditionalOnMissingBean
+    public DefaultSecurityManager securityManager() {
+        DefaultSecurityManager sm = new DefaultWebSecurityManager();
+        sm.setCacheManager(cacheManager());
+        return sm;
+    }
+
+    @Bean(name = "shiroFilter")
+    @DependsOn("securityManager")
+    @ConditionalOnMissingBean
+    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultSecurityManager securityManager, Realm realm) {
+        securityManager.setRealm(realm);
+
+        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
+        shiroFilter.setSecurityManager(securityManager);
+        shiroFilter.setLoginUrl("/admin/login");
+        shiroFilter.setSuccessUrl("/admin/index");
+        shiroFilter.setUnauthorizedUrl("/previlige/no");
+        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
+        filterChainDefinitionMap.put("/assets/**", "anon");
+
+        filterChainDefinitionMap.put("/admin/login", "anon");
+
+        List<com.fourdage.system.entity.Resource> list = resourceService.findAll();
+        for (com.fourdage.system.entity.Resource resource : list) {
+            filterChainDefinitionMap.put(resource.getSourceUrl(), "perms[" + resource.getSourceKey() + "]");
+        }
+
+//		filterChainDefinitionMap.put("/admin/user/index", "perms[system:user:index]");
+//		filterChainDefinitionMap.put("/admin/user/add", "perms[system:user:add]");
+//		filterChainDefinitionMap.put("/admin/user/edit*", "perms[system:user:edit]");
+//		filterChainDefinitionMap.put("/admin/user/deleteBatch", "perms[system:user:deleteBatch]");
+//		filterChainDefinitionMap.put("/admin/user/grant/**", "perms[system:user:grant]");
+
+//		filterChainDefinitionMap.put("/admin/role/index", "perms[system:role:index]");
+//		filterChainDefinitionMap.put("/admin/role/add", "perms[system:role:add]");
+//		filterChainDefinitionMap.put("/admin/role/edit*", "perms[system:role:edit]");
+//		filterChainDefinitionMap.put("/admin/role/deleteBatch", "perms[system:role:deleteBatch]");
+//		filterChainDefinitionMap.put("/admin/role/grant/**", "perms[system:role:grant]");
+
+//		filterChainDefinitionMap.put("/admin/resource/index", "perms[system:resource:index]");
+//		filterChainDefinitionMap.put("/admin/resource/add", "perms[system:resource:add]");
+//		filterChainDefinitionMap.put("/admin/resource/edit*", "perms[system:resource:edit]");
+//		filterChainDefinitionMap.put("/admin/resource/deleteBatch", "perms[system:resource:deleteBatch]");
+
+        filterChainDefinitionMap.put("/admin/**", "authc");
+        shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
+        return shiroFilter;
+    }
+}

+ 54 - 0
src/main/java/com/fourdage/base/config/shiro/ShiroManager.java

@@ -0,0 +1,54 @@
+package com.fourdage.base.config.shiro;
+
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.apache.shiro.spring.LifecycleBeanPostProcessor;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.DependsOn;
+
+/**
+ * Shiro Config Manager.
+ *
+ * @author SPPan
+ */
+public class ShiroManager {
+
+    /**
+     * 保证实现了Shiro内部lifecycle函数的bean执行
+     */
+    @Bean(name = "lifecycleBeanPostProcessor")
+    @ConditionalOnMissingBean
+    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
+        return new LifecycleBeanPostProcessor();
+    }
+
+    /**
+     * 开启注解控制权限的方式,AOP式方法级权限检查
+     *
+     * @return
+     */
+    @Bean(name = "defaultAdvisorAutoProxyCreator")
+    @ConditionalOnMissingBean
+    @DependsOn("lifecycleBeanPostProcessor")
+    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
+        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
+        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
+        return defaultAdvisorAutoProxyCreator;
+    }
+
+    /**
+     * 开启注解控制权限的方式
+     *
+     * @param securityManager
+     * @return
+     */
+    @Bean
+    @ConditionalOnMissingBean
+    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultSecurityManager securityManager) {
+        AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
+        aasa.setSecurityManager(securityManager);
+        return aasa;
+    }
+}

+ 44 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/AuthenticatedTag.java

@@ -0,0 +1,44 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.log.Logger;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.util.Map;
+
+
+/**
+ * JSP tag that renders the tag body only if the current user has executed a <b>successful</b> authentication attempt
+ * <em>during their current session</em>.
+ * <p>
+ * <p>This is more restrictive than the {@link UserTag}, which only
+ * ensures the current user is known to the system, either via a current login or from Remember Me services,
+ * which only makes the assumption that the current user is who they say they are, and does not guarantee it like
+ * this tag does.
+ * <p>
+ * <p>The logically opposite tag of this one is the {@link NotAuthenticatedTag}
+ * <p>
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.AuthenticatedTag}</p>
+ *
+ * @since 0.2
+ */
+public class AuthenticatedTag extends SecureTag {
+    private static final Logger log = Logger.getLogger("AuthenticatedTag");
+
+    @Override
+    public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
+        if (getSubject() != null && getSubject().isAuthenticated()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Subject exists and is authenticated.  Tag body will be evaluated.");
+            }
+
+            renderBody(env, body);
+        } else {
+            if (log.isDebugEnabled()) {
+                log.debug("Subject does not exist or is not authenticated.  Tag body will not be evaluated.");
+            }
+        }
+    }
+}

+ 42 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/GuestTag.java

@@ -0,0 +1,42 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.log.Logger;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.util.Map;
+
+
+/**
+ * JSP tag that renders the tag body if the current user <em>is not</em> known to the system, either because they
+ * haven't logged in yet, or because they have no 'RememberMe' identity.
+ * <p>
+ * <p>The logically opposite tag of this one is the {@link UserTag}.  Please read that class's JavaDoc as it explains
+ * more about the differences between Authenticated/Unauthenticated and User/Guest semantic differences.
+ * <p>
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.GuestTag}</p>
+ *
+ * @since 0.9
+ */
+public class GuestTag extends SecureTag {
+    private static final Logger log = Logger.getLogger("AuthenticatedTag");
+
+    @Override
+    public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
+        if (getSubject() == null || getSubject().getPrincipal() == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("Subject does not exist or does not have a known identity (aka 'principal').  " +
+                        "Tag body will be evaluated.");
+            }
+
+            renderBody(env, body);
+        } else {
+            if (log.isDebugEnabled()) {
+                log.debug("Subject exists or has a known identity (aka 'principal').  " +
+                        "Tag body will not be evaluated.");
+            }
+        }
+    }
+}

+ 51 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/HasAnyRolesTag.java

@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.fourdage.base.config.shiro.freemarker;
+
+import org.apache.shiro.subject.Subject;
+
+
+/**
+ * Displays body content if the current user has any of the roles specified.
+ * <p>
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.HasAnyRolesTag}</p>
+ *
+ * @since 0.2
+ */
+public class HasAnyRolesTag extends RoleTag {
+    // Delimeter that separates role names in tag attribute
+    private static final String ROLE_NAMES_DELIMETER = ",";
+
+    protected boolean showTagBody(String roleNames) {
+        boolean hasAnyRole = false;
+        Subject subject = getSubject();
+
+        if (subject != null) {
+            // Iterate through roles and check to see if the user has one of the roles
+            for (String role : roleNames.split(ROLE_NAMES_DELIMETER)) {
+                if (subject.hasRole(role.trim())) {
+                    hasAnyRole = true;
+                    break;
+                }
+            }
+        }
+
+        return hasAnyRole;
+    }
+}

+ 12 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/HasPermissionTag.java

@@ -0,0 +1,12 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.HasPermissionTag}</p>
+ *
+ * @since 0.1
+ */
+public class HasPermissionTag extends PermissionTag {
+    protected boolean showTagBody(String p) {
+        return isPermitted(p);
+    }
+}

+ 10 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/HasRoleTag.java

@@ -0,0 +1,10 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.HasRoleTag}</p>
+ */
+public class HasRoleTag extends RoleTag {
+    protected boolean showTagBody(String roleName) {
+        return getSubject() != null && getSubject().hasRole(roleName);
+    }
+}

+ 10 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/LacksPermissionTag.java

@@ -0,0 +1,10 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.LacksPermissionTag}</p>
+ */
+public class LacksPermissionTag extends PermissionTag {
+    protected boolean showTagBody(String p) {
+        return !isPermitted(p);
+    }
+}

+ 11 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/LacksRoleTag.java

@@ -0,0 +1,11 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.LacksRoleTag}</p>
+ */
+public class LacksRoleTag extends RoleTag {
+    protected boolean showTagBody(String roleName) {
+        boolean hasRole = getSubject() != null && getSubject().hasRole(roleName);
+        return !hasRole;
+    }
+}

+ 32 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/NotAuthenticatedTag.java

@@ -0,0 +1,32 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.log.Logger;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.util.Map;
+
+
+/**
+ * Freemarker tag that renders the tag body only if the current user has <em>not</em> executed a successful authentication
+ * attempt <em>during their current session</em>.
+ * <p>
+ * <p>The logically opposite tag of this one is the {@link org.apache.shiro.web.tags.AuthenticatedTag}.
+ * <p>
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.NotAuthenticatedTag}</p>
+ */
+public class NotAuthenticatedTag extends SecureTag {
+    static final Logger log = Logger.getLogger("NotAuthenticatedTag");
+
+    @Override
+    public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
+        if (getSubject() == null || !getSubject().isAuthenticated()) {
+            log.debug("Subject does not exist or is not authenticated.  Tag body will be evaluated.");
+            renderBody(env, body);
+        } else {
+            log.debug("Subject exists and is authenticated.  Tag body will not be evaluated.");
+        }
+    }
+}

+ 43 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/PermissionTag.java

@@ -0,0 +1,43 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModelException;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.PermissionTag}</p>
+ */
+public abstract class PermissionTag extends SecureTag {
+    String getName(Map params) {
+        return getParam(params, "name");
+    }
+
+    @Override
+    protected void verifyParameters(Map params) throws TemplateModelException {
+        String permission = getName(params);
+
+        if (permission == null || permission.length() == 0) {
+            throw new TemplateModelException("The 'name' tag attribute must be set.");
+        }
+    }
+
+    @Override
+    public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
+        String p = getName(params);
+
+        boolean show = showTagBody(p);
+        if (show) {
+            renderBody(env, body);
+        }
+    }
+
+    protected boolean isPermitted(String p) {
+        return getSubject() != null && getSubject().isPermitted(p);
+    }
+
+    protected abstract boolean showTagBody(String p);
+}

+ 119 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/PrincipalTag.java

@@ -0,0 +1,119 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.log.Logger;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModelException;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * <p>Tag used to print out the String value of a user's default principal,
+ * or a specific principal as specified by the tag's attributes.</p>
+ * <p>
+ * <p> If no attributes are specified, the tag prints out the <tt>toString()</tt>
+ * value of the user's default principal.  If the <tt>type</tt> attribute
+ * is specified, the tag looks for a principal with the given type.  If the
+ * <tt>property</tt> attribute is specified, the tag prints the string value of
+ * the specified property of the principal.  If no principal is found or the user
+ * is not authenticated, the tag displays nothing unless a <tt>defaultValue</tt>
+ * is specified.</p>
+ * <p>
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.PrincipalTag}</p>
+ *
+ * @since 0.2
+ */
+public class PrincipalTag extends SecureTag {
+    static final Logger log = Logger.getLogger("PrincipalTag");
+
+    /**
+     * The type of principal to be retrieved, or null if the default principal should be used.
+     */
+    String getType(Map params) {
+        return getParam(params, "type");
+    }
+
+    /**
+     * The property name to retrieve of the principal, or null if the <tt>toString()</tt> value should be used.
+     */
+    String getProperty(Map params) {
+        return getParam(params, "property");
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
+        String result = null;
+
+        if (getSubject() != null) {
+            // Get the principal to print out
+            Object principal;
+
+            if (getType(params) == null) {
+                principal = getSubject().getPrincipal();
+            } else {
+                principal = getPrincipalFromClassName(params);
+            }
+
+            // Get the string value of the principal
+            if (principal != null) {
+                String property = getProperty(params);
+
+                if (property == null) {
+                    result = principal.toString();
+                } else {
+                    result = getPrincipalProperty(principal, property);
+                }
+            }
+        }
+
+        // Print out the principal value if not null
+        if (result != null) {
+            try {
+                env.getOut().write(result);
+            } catch (IOException ex) {
+                throw new TemplateException("Error writing [" + result + "] to Freemarker.", ex, env);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    Object getPrincipalFromClassName(Map params) {
+        String type = getType(params);
+
+        try {
+            Class cls = Class.forName(type);
+
+            return getSubject().getPrincipals().oneByType(cls);
+        } catch (ClassNotFoundException ex) {
+            log.error("Unable to find class for name [" + type + "]", ex);
+        }
+
+        return null;
+    }
+
+    String getPrincipalProperty(Object principal, String property) throws TemplateModelException {
+        try {
+            BeanInfo beanInfo = Introspector.getBeanInfo(principal.getClass());
+
+            // Loop through the properties to get the string value of the specified property
+            for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
+                if (propertyDescriptor.getName().equals(property)) {
+                    Object value = propertyDescriptor.getReadMethod().invoke(principal, (Object[]) null);
+
+                    return String.valueOf(value);
+                }
+            }
+
+            // property not found, throw
+            throw new TemplateModelException("Property [" + property + "] not found in principal of type [" + principal.getClass().getName() + "]");
+        } catch (Exception ex) {
+            throw new TemplateModelException("Error reading property [" + property + "] from principal of type [" + principal.getClass().getName() + "]", ex);
+        }
+    }
+}

+ 27 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/RoleTag.java

@@ -0,0 +1,27 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.RoleTag}</p>
+ */
+public abstract class RoleTag extends SecureTag {
+    String getName(Map params) {
+        return getParam(params, "name");
+    }
+
+    @Override
+    public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
+        boolean show = showTagBody(getName(params));
+        if (show) {
+            renderBody(env, body);
+        }
+    }
+
+    protected abstract boolean showTagBody(String roleName);
+}

+ 44 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/SecureTag.java

@@ -0,0 +1,44 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.template.*;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.SecureTag}</p>
+ */
+public abstract class SecureTag implements TemplateDirectiveModel {
+    public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
+        verifyParameters(params);
+        render(env, params, body);
+    }
+
+    public abstract void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException;
+
+    protected String getParam(Map params, String name) {
+        Object value = params.get(name);
+
+        if (value instanceof SimpleScalar) {
+            return ((SimpleScalar) value).getAsString();
+        }
+
+        return null;
+    }
+
+    protected Subject getSubject() {
+        return SecurityUtils.getSubject();
+    }
+
+    protected void verifyParameters(Map params) throws TemplateModelException {
+    }
+
+    protected void renderBody(Environment env, TemplateDirectiveBody body) throws IOException, TemplateException {
+        if (body != null) {
+            body.render(env.getOut());
+        }
+    }
+}

+ 23 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/ShiroTags.java

@@ -0,0 +1,23 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+import freemarker.template.SimpleHash;
+
+/**
+ * Shortcut for injecting the tags into Freemarker
+ * <p>
+ * <p>Usage: cfg.setSharedVeriable("shiro", new ShiroTags());</p>
+ */
+public class ShiroTags extends SimpleHash {
+    public ShiroTags() {
+        put("authenticated", new AuthenticatedTag());
+        put("guest", new GuestTag());
+        put("hasAnyRoles", new HasAnyRolesTag());
+        put("hasPermission", new HasPermissionTag());
+        put("hasRole", new HasRoleTag());
+        put("lacksPermission", new LacksPermissionTag());
+        put("lacksRole", new LacksRoleTag());
+        put("notAuthenticated", new NotAuthenticatedTag());
+        put("principal", new PrincipalTag());
+        put("user", new UserTag());
+    }
+}

+ 37 - 0
src/main/java/com/fourdage/base/config/shiro/freemarker/UserTag.java

@@ -0,0 +1,37 @@
+package com.fourdage.base.config.shiro.freemarker;
+
+import freemarker.core.Environment;
+import freemarker.log.Logger;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Freemarker tag that renders the tag body if the current user known to the system, either from a successful login attempt
+ * (not necessarily during the current session) or from 'RememberMe' services.
+ * <p>
+ * <p><b>Note:</b> This is <em>less</em> restrictive than the <code>AuthenticatedTag</code> since it only assumes
+ * the user is who they say they are, either via a current session login <em>or</em> via Remember Me services, which
+ * makes no guarantee the user is who they say they are.  The <code>AuthenticatedTag</code> however
+ * guarantees that the current user has logged in <em>during their current session</em>, proving they really are
+ * who they say they are.
+ * <p>
+ * <p>The logically opposite tag of this one is the {@link org.apache.shiro.web.tags.GuestTag}.
+ * <p>
+ * <p>Equivalent to {@link org.apache.shiro.web.tags.UserTag}</p>
+ */
+public class UserTag extends SecureTag {
+    static final Logger log = Logger.getLogger("UserTag");
+
+    @Override
+    public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException {
+        if (getSubject() != null && getSubject().getPrincipal() != null) {
+            log.debug("Subject has known identity (aka 'principal'). Tag body will be evaluated.");
+            renderBody(env, body);
+        } else {
+            log.debug("Subject does not exist or have a known identity (aka 'principal'). Tag body will not be evaluated.");
+        }
+    }
+}

+ 13 - 0
src/main/java/com/fourdage/base/controller/AdminIndexController.java

@@ -0,0 +1,13 @@
+package com.fourdage.base.controller;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class AdminIndexController extends BaseController {
+    @RequestMapping(value = {"/admin/", "/admin/index"})
+    public String index() {
+
+        return "admin/index";
+    }
+}

+ 118 - 0
src/main/java/com/fourdage/base/controller/BaseController.java

@@ -0,0 +1,118 @@
+package com.fourdage.base.controller;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.propertyeditors.StringTrimmerEditor;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+
+import com.fourdage.base.common.DateEditor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Date;
+
+public class BaseController {
+    @Autowired
+    protected HttpServletRequest request;
+
+    @Autowired
+    protected HttpServletResponse response;
+
+    @InitBinder
+    protected void initBinder(WebDataBinder webDataBinder) {
+        webDataBinder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
+        webDataBinder.registerCustomEditor(Date.class, new DateEditor(true));
+    }
+
+    /**
+     * 带参重定向
+     *
+     * @param path
+     * @return
+     */
+    protected String redirect(String path) {
+        return "redirect:" + path;
+    }
+
+    /**
+     * 不带参重定向
+     *
+     * @param response
+     * @param path
+     * @return
+     */
+    protected String redirect(HttpServletResponse response, String path) {
+        try {
+            response.sendRedirect(path);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 获取分页请求
+     *
+     * @return
+     */
+    protected PageRequest getPageRequest() {
+        int page = 0;
+        int size = 10;
+        Sort sort = null;
+        String sortName = request.getParameter("sortName");
+        String sortOrder = request.getParameter("sortOrder");
+        if (StringUtils.isNoneBlank(sortName) && StringUtils.isNoneBlank(sortOrder)) {
+            if (sortOrder.equalsIgnoreCase("desc")) {
+                sort = new Sort(Direction.DESC, sortName);
+            } else {
+                sort = new Sort(Direction.ASC, sortName);
+            }
+        }
+        String pageNumber = request.getParameter("pageNumber");
+        if (StringUtils.isNotBlank(pageNumber)) {
+            page = Integer.parseInt(pageNumber) - 1;
+        }
+        String pageSize = request.getParameter("pageSize");
+        if (StringUtils.isNotBlank(pageSize)) {
+            size = Integer.parseInt(pageSize);
+        }
+        PageRequest pageRequest = new PageRequest(page, size, sort);
+        return pageRequest;
+    }
+
+    /**
+     * 获取分页请求
+     *
+     * @param sort 排序条件
+     * @return
+     */
+    protected PageRequest getPageRequest(Sort sort) {
+        int page = 0;
+        int size = 10;
+        String sortName = request.getParameter("sortName");
+        String sortOrder = request.getParameter("sortOrder");
+        if (StringUtils.isNoneBlank(sortName) && StringUtils.isNoneBlank(sortOrder)) {
+            if (sortOrder.equalsIgnoreCase("desc")) {
+                sort.and(new Sort(Direction.DESC, sortName));
+            } else {
+                sort.and(new Sort(Direction.ASC, sortName));
+            }
+        }
+        String pageNumber = request.getParameter("pageNumber");
+        if (StringUtils.isNotBlank(pageNumber)) {
+            page = Integer.parseInt(pageNumber) - 1;
+        }
+        String pageSize = request.getParameter("pageSize");
+        if (StringUtils.isNotBlank(pageSize)) {
+            size = Integer.parseInt(pageSize);
+        }
+        PageRequest pageRequest = new PageRequest(page, size, sort);
+        return pageRequest;
+    }
+
+}

+ 100 - 0
src/main/java/com/fourdage/base/controller/LoginController.java

@@ -0,0 +1,100 @@
+package com.fourdage.base.controller;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.subject.Subject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fourdage.base.common.HttpHelper;
+import com.fourdage.dingding.entity.Department;
+import com.fourdage.dingding.service.IDepartmentService;
+import com.fourdage.dingding.util.DingDingUtil;
+import com.fourdage.system.entity.User;
+
+@Controller
+public class LoginController extends BaseController {
+	
+	private Logger logger = LoggerFactory.getLogger(getClass());
+	
+	@Autowired
+	private DingDingUtil dingDingUtil;
+	@Autowired
+	private IDepartmentService departmentService;
+	
+    @RequestMapping(value = {"/admin/login"}, method = RequestMethod.GET)
+    public String login() {
+        return "admin/login";
+    }
+
+    @RequestMapping(value = {"/admin/login"}, method = RequestMethod.POST)
+    public String login(@RequestParam("username") String username,
+                        @RequestParam("password") String password,
+                        ModelMap model) {
+        try {
+            Subject subject = SecurityUtils.getSubject();
+            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
+            subject.login(token);
+            
+            logger.info("获取钉钉部门和用户信息");
+            try {
+            	String region = dingDingUtil.getRegion();
+    			Map<String, Object> param = new HashMap<String, Object>();
+    			param.put("access_token", dingDingUtil.getAccessToken());
+    			
+    			String resultStr = HttpHelper.sendGetByUrlConnection("https://oapi.dingtalk.com/department/list", param, "UTF-8");
+    			JSONObject resultStrObject = JSON.parseObject(resultStr);
+    			JSONArray arr = resultStrObject.getJSONArray("department");
+    			if (arr != null && arr.size() > 0){
+    				for (Object object : arr){
+    					JSONObject jobj = (JSONObject)object;
+    					
+    					List<Department> depts = departmentService.findByDeptId(jobj.getString("id"));
+    					if (depts != null && depts.size() > 0){
+    						Department update = depts.get(0);
+    						update.setDeptName(jobj.getString("name"));
+    						update.setParentId(jobj.getString("parentid"));
+    						departmentService.update(update);
+    					}else{
+    						Department insert = new Department();
+    						insert.setDeptId(jobj.getString("id"));
+    						insert.setDeptName(jobj.getString("name"));
+    						insert.setRegion(region);
+    						insert.setParentId(jobj.getString("parentid"));
+    						insert.setRecStatus("A");
+    						departmentService.save(insert);
+    					}
+    				}
+    			}
+            } catch (Exception e) {
+            	logger.error("系统异常:", e);
+            }
+            return redirect("/admin/index");
+        } catch (AuthenticationException e) {
+            model.put("message", e.getMessage());
+        }
+        return "admin/login";
+    }
+
+    @RequestMapping(value = {"/admin/logout"}, method = RequestMethod.GET)
+    public String logout() {
+        Subject subject = SecurityUtils.getSubject();
+        subject.logout();
+        return redirect("admin/login");
+    }
+
+}

+ 15 - 0
src/main/java/com/fourdage/base/dao/IBaseDao.java

@@ -0,0 +1,15 @@
+package com.fourdage.base.dao;
+
+import java.io.Serializable;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.repository.NoRepositoryBean;
+
+import com.fourdage.base.entity.BaseEntity;
+
+@NoRepositoryBean
+public interface IBaseDao<T extends BaseEntity, ID extends Serializable>
+        extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
+
+}

+ 15 - 0
src/main/java/com/fourdage/base/entity/BaseEntity.java

@@ -0,0 +1,15 @@
+package com.fourdage.base.entity;
+
+import java.io.Serializable;
+
+import javax.persistence.MappedSuperclass;
+
+@MappedSuperclass
+public abstract class BaseEntity implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -250118731239275742L;
+
+}

+ 45 - 0
src/main/java/com/fourdage/base/service/IBaseService.java

@@ -0,0 +1,45 @@
+package com.fourdage.base.service;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+
+import java.io.Serializable;
+import java.util.List;
+
+public interface IBaseService<T, ID extends Serializable> {
+    public abstract T find(ID id);
+
+    public abstract List<T> findAll();
+
+    public abstract List<T> findList(ID[] ids);
+
+    public abstract List<T> findList(Iterable<ID> ids);
+
+    public abstract Page<T> findAll(Pageable pageable);
+
+    public abstract Page<T> findAll(Specification<T> spec, Pageable pageable);
+
+    public abstract long count();
+
+    public abstract long count(Specification<T> spec);
+
+    public abstract boolean exists(ID id);
+
+    public abstract void save(T entity);
+
+    public abstract T update(T entity);
+
+    public abstract void delete(ID id);
+
+    public abstract void deleteByIds(@SuppressWarnings("unchecked") ID... ids);
+
+    public abstract void delete(T[] entitys);
+
+    public void delete(Iterable<T> entitys);
+
+    public abstract void delete(T entity);
+
+    public List<T> findList(Specification<T> spec, Sort sort);
+}

+ 120 - 0
src/main/java/com/fourdage/base/service/impl/BaseServiceImpl.java

@@ -0,0 +1,120 @@
+package com.fourdage.base.service.impl;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.transaction.Transactional;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+
+import com.fourdage.base.dao.IBaseDao;
+import com.fourdage.base.entity.BaseEntity;
+import com.fourdage.base.service.IBaseService;
+
+@Transactional
+public abstract class BaseServiceImpl<T extends BaseEntity, ID extends Serializable> implements IBaseService<T, ID> {
+
+    public abstract IBaseDao<T, ID> getBaseDao();
+
+    @Override
+    public T find(ID id) {
+        return getBaseDao().findOne(id);
+    }
+
+    @Override
+    public List<T> findAll() {
+        return getBaseDao().findAll();
+    }
+
+    @Override
+    public List<T> findList(ID[] ids) {
+        List<ID> idList = Arrays.asList(ids);
+        return getBaseDao().findAll(idList);
+    }
+
+    @Override
+    public List<T> findList(Specification<T> spec, Sort sort) {
+        return getBaseDao().findAll(spec, sort);
+    }
+
+    @Override
+    public Page<T> findAll(Pageable pageable) {
+        return getBaseDao().findAll(pageable);
+    }
+
+    @Override
+    public long count() {
+        return getBaseDao().count();
+    }
+
+    @Override
+    public long count(Specification<T> spec) {
+        return getBaseDao().count(spec);
+    }
+
+    @Override
+    public boolean exists(ID id) {
+        return getBaseDao().exists(id);
+    }
+
+    @Override
+    public void save(T entity) {
+        getBaseDao().save(entity);
+    }
+
+    public void save(Iterable<T> entitys) {
+        getBaseDao().save(entitys);
+    }
+
+    @Override
+    public T update(T entity) {
+        return getBaseDao().saveAndFlush(entity);
+    }
+
+    @Override
+    public void delete(ID id) {
+        getBaseDao().delete(id);
+    }
+
+    @Override
+    public void deleteByIds(@SuppressWarnings("unchecked") ID... ids) {
+        if (ids != null) {
+            for (int i = 0; i < ids.length; i++) {
+                ID id = ids[i];
+                this.delete(id);
+            }
+        }
+    }
+
+    @Override
+    public void delete(T[] entitys) {
+        List<T> tList = Arrays.asList(entitys);
+        getBaseDao().delete(tList);
+    }
+
+    @Override
+    public void delete(Iterable<T> entitys) {
+        getBaseDao().delete(entitys);
+    }
+
+    @Override
+    public void delete(T entity) {
+        getBaseDao().delete(entity);
+    }
+
+    @Override
+    public List<T> findList(Iterable<ID> ids) {
+        return getBaseDao().findAll(ids);
+    }
+
+    @Override
+    public Page<T> findAll(Specification<T> spec, Pageable pageable) {
+        // TODO Auto-generated method stub
+        return getBaseDao().findAll(spec, pageable);
+    }
+
+}

+ 76 - 0
src/main/java/com/fourdage/base/vo/ZtreeView.java

@@ -0,0 +1,76 @@
+package com.fourdage.base.vo;
+
+import java.io.Serializable;
+
+/**
+ * ztree树
+ */
+public class ZtreeView implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 6237809780035784312L;
+
+    private Long id;
+
+    private Long pId;
+
+    private String name;
+
+    private boolean open;
+
+    private boolean checked = false;
+
+    public ZtreeView() {
+    }
+
+    public ZtreeView(Long id, Long pId, String name, boolean open) {
+        super();
+        this.id = id;
+        this.pId = pId;
+        this.name = name;
+        this.open = open;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getpId() {
+        return pId;
+    }
+
+    public void setpId(Long pId) {
+        this.pId = pId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public boolean isOpen() {
+        return open;
+    }
+
+    public void setOpen(boolean open) {
+        this.open = open;
+    }
+
+    public boolean isChecked() {
+        return checked;
+    }
+
+    public void setChecked(boolean checked) {
+        this.checked = checked;
+    }
+
+}