├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src ├── main ├── java │ └── love │ │ └── sola │ │ └── netsupport │ │ ├── Index.java │ │ ├── api │ │ ├── API.java │ │ ├── APIRouter.java │ │ ├── CheckSession.java │ │ ├── Error.java │ │ ├── Login.java │ │ ├── manager │ │ │ ├── GetUser.java │ │ │ └── TicketPush.java │ │ ├── root │ │ │ ├── DashBoard.java │ │ │ ├── FlushCache.java │ │ │ └── SetPassword.java │ │ ├── stuff │ │ │ ├── TicketLog.java │ │ │ ├── TicketLookup.java │ │ │ ├── TicketTrack.java │ │ │ ├── TicketUpdate.java │ │ │ └── ToolsCheck.java │ │ └── user │ │ │ ├── ProfileModify.java │ │ │ ├── Register.java │ │ │ ├── TicketQuery.java │ │ │ └── TicketSubmit.java │ │ ├── auth │ │ ├── OAuth2.java │ │ └── OAuth2Handler.java │ │ ├── config │ │ ├── Lang.java │ │ └── Settings.java │ │ ├── enums │ │ ├── Access.java │ │ ├── Attribute.java │ │ ├── Block.java │ │ ├── ISP.java │ │ ├── ISPConverter.java │ │ └── Status.java │ │ ├── pojo │ │ ├── Operator.java │ │ ├── Ticket.java │ │ ├── ToolsCheck.java │ │ └── User.java │ │ ├── session │ │ ├── MapSession.java │ │ ├── MapSessionRepository.java │ │ ├── WechatSession.java │ │ └── WxSession.java │ │ ├── sql │ │ ├── SQLCore.java │ │ ├── TableConfig.java │ │ ├── TableOperator.java │ │ ├── TableTicket.java │ │ └── TableUser.java │ │ ├── util │ │ ├── Checker.java │ │ ├── Crypto.java │ │ ├── ParseUtil.java │ │ └── Redirect.java │ │ └── wechat │ │ ├── Command.java │ │ ├── WxMpServlet.java │ │ ├── handler │ │ ├── AutoReplyHandler.java │ │ ├── CancelHandler.java │ │ ├── ProfileHandler.java │ │ ├── QueryHandler.java │ │ ├── RegisterHandler.java │ │ ├── SubmitHandler.java │ │ ├── SubscribeHandler.java │ │ └── admin │ │ │ ├── LoginHandler.java │ │ │ ├── OperatorInfoHandler.java │ │ │ └── SignHandler.java │ │ └── matcher │ │ ├── CheckSpamMatcher.java │ │ ├── CommandMatcher.java │ │ └── RegisterMatcher.java ├── resources │ ├── hibernate.cfg.xml │ ├── lang.yml │ ├── menu-op.json │ └── menu.json └── webapp │ ├── META-INF │ └── context.xml │ ├── WEB-INF │ └── web.xml │ └── favicon.ico └── test └── java └── love └── sola └── netsupport ├── api └── ReflectionTest.java ├── config └── ReflectionTest.java ├── enums └── ReflectionTest.java └── util ├── GsonTest.java └── URLEncodeTest.java /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset=utf-8 3 | end_of_line=lf 4 | trim_trailing_whitespace=true 5 | insert_final_newline=true 6 | indent_style=space 7 | indent_size=4 8 | 9 | [*.json] 10 | indent_style=space 11 | indent_size=2 12 | 13 | [{*.ddl,*.sql}] 14 | indent_style=space 15 | indent_size=2 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /docs 2 | .idea/ 3 | *.iml 4 | /target 5 | .vscode -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WechatTicketSystem 2 | WechatTicketSystem is a basic ticket system for network maintaining, based on Wechat. 3 | 4 | ## Build 5 | ### Requirements 6 | - [Apache Maven](https://maven.apache.org/) (latest version recommended) 7 | 8 | ### Steps 9 | 1. Clone the git repository `git clone https://github.com/ZSCNetSupportDept/WechatTicketSystem.git` 10 | 2. Change dir to project root (where the `pom.xml` is) 11 | 3. Build with Maven `mvn clean package` 12 | 4. The out file will be in `target/` folder 13 | 14 | ## Contributing 15 | ### Code Style 16 | The code style configuration is [here](http://stash.sola.love/projects/PSS/repos/ide_configuration/browse/intellij%20idea/Code_Style_Use_Tab.xml). 17 | 18 | In Intellij IDEA, you can import the configuration by Settings-\>Editor-\>Code Style-\>Manage(at right side)-\>Import.. 19 | ### Pull Request 20 | Please notice that the pull requests should compare with `develop` branch instead of `master`, 21 | submit pull requests to `master` branch will be ignored. 22 | ## TroubleShooting 23 | - Before you report a bug, please [search the issue tracker](https://github.com/ZSCNetSupportDept/WechatTicketSystem/issues) to see if someone has already reported the problem. 24 | - If the issue doesn’t already exist, [create a new issue](https://github.com/ZSCNetSupportDept/WechatTicketSystem/issues/new). 25 | - Please provide as much information as possible with the issue report, we like to know the version you are using, as well as your Operating System and JVM version. 26 | - If you need to paste code, or include a stack trace use Markdown ```` ``` ```` escapes before and after your text. 27 | 28 | ## License 29 | WechatTicketSystem is distributed under the GNU Lesser General Public License v3.0 (LGPLv3). 30 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | WechatTicketSystem 7 | love.sola.netsupport 8 | WechatTicketSystem 9 | 2.2-SNAPSHOT 10 | war 11 | 12 | 13 | UTF-8 14 | 1.8 15 | 1.8 16 | 1.8 17 | 18 | 19 | 20 | 21 | 22 | org.apache.maven.plugins 23 | maven-compiler-plugin 24 | 3.3 25 | 26 | 1.8 27 | 1.8 28 | 29 | 30 | 31 | org.apache.tomcat.maven 32 | tomcat7-maven-plugin 33 | 2.2 34 | 35 | http://localhost:8080/manager/text 36 | wwbx 37 | /WechatTicketSystem 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-war-plugin 43 | 3.3.2 44 | 45 | 46 | 47 | 48 | 49 | 50 | javax.servlet 51 | javax.servlet-api 52 | 3.1.0 53 | provided 54 | 55 | 56 | junit 57 | junit 58 | 4.12 59 | test 60 | 61 | 62 | org.slf4j 63 | slf4j-simple 64 | 1.7.12 65 | 66 | 67 | com.google.guava 68 | guava 69 | 19.0-rc2 70 | 71 | 72 | com.google.code.gson 73 | gson 74 | 2.4 75 | 76 | 77 | org.apache.commons 78 | commons-io 79 | 1.3.2 80 | 81 | 82 | org.apache.commons 83 | commons-lang3 84 | 3.4 85 | 86 | 87 | commons-net 88 | commons-net 89 | 3.3 90 | 91 | 92 | me.chanjar 93 | weixin-java-mp 94 | 1.3.3 95 | 96 | 97 | com.mchange 98 | c3p0 99 | 0.9.5.4 100 | 101 | 102 | mysql 103 | mysql-connector-java 104 | 5.1.37 105 | 106 | 107 | org.hibernate 108 | hibernate-core 109 | 5.0.3.Final 110 | 111 | 112 | org.hibernate 113 | hibernate-entitymanager 114 | 5.0.3.Final 115 | 116 | 117 | org.hibernate 118 | hibernate-c3p0 119 | 5.0.3.Final 120 | 121 | 122 | org.hibernate.javax.persistence 123 | hibernate-jpa-2.1-api 124 | 1.0.0.Final 125 | 126 | 127 | org.hibernate 128 | hibernate-envers 129 | 5.0.3.Final 130 | 131 | 132 | de.svenkubiak 133 | jBCrypt 134 | 0.4 135 | 136 | 137 | org.yaml 138 | snakeyaml 139 | 1.16 140 | 141 | 142 | org.reflections 143 | reflections 144 | 0.9.10 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/Index.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport; 19 | 20 | import java.io.IOException; 21 | import java.io.PrintWriter; 22 | 23 | import javax.servlet.ServletException; 24 | import javax.servlet.annotation.WebServlet; 25 | import javax.servlet.http.HttpServlet; 26 | import javax.servlet.http.HttpServletRequest; 27 | import javax.servlet.http.HttpServletResponse; 28 | 29 | /** 30 | * @author Sola {@literal } 31 | */ 32 | @WebServlet(name = "Index", urlPatterns = "/index", loadOnStartup = 1) 33 | public class Index extends HttpServlet { 34 | 35 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 36 | doGet(request, response); 37 | } 38 | 39 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 40 | request.setCharacterEncoding("utf-8"); 41 | response.addHeader("Content-type", "text/plain;charset=utf-8"); 42 | response.setCharacterEncoding("utf-8"); 43 | PrintWriter out = response.getWriter(); 44 | out.println("Wechat Ticket System (WTS) 0.1 Copyright 2015-2016 Sola & LiuYue all rights reserved. | Commercial license for ZSC Network Support Department (ZSCNSD)."); 45 | out.println("For any problem, Please contact loli@sola.love."); 46 | if (response.getStatus() == HttpServletResponse.SC_NOT_FOUND) { 47 | out.println("\nError 404: Page not found."); 48 | } 49 | out.close(); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/API.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api; 19 | 20 | import org.apache.commons.lang3.time.DateUtils; 21 | 22 | import java.util.Calendar; 23 | import java.util.Date; 24 | 25 | import javax.servlet.http.HttpServletRequest; 26 | 27 | import love.sola.netsupport.enums.Access; 28 | import love.sola.netsupport.session.WxSession; 29 | import love.sola.netsupport.wechat.Command; 30 | 31 | /** 32 | * @author Sola {@literal } 33 | */ 34 | public abstract class API { 35 | 36 | public String url = null; //url 37 | public int access = Access.GOD_MODE; //operator's permission 38 | public Command authorize = null; //session check 39 | 40 | protected abstract Object process(HttpServletRequest req, WxSession session) throws Exception; 41 | 42 | @Override 43 | public String toString() { 44 | return getClass().getSimpleName() + "{" + 45 | "url='" + url + '\'' + 46 | ", access=" + Access.inverseMap.get(access) + 47 | ", authorize=" + authorize + 48 | '}'; 49 | } 50 | 51 | public static String getParameterWithDefault(String obj, String def) { 52 | return obj == null ? def : obj; 53 | } 54 | 55 | public static Date getParameterAsDate(String obj, Date def) { 56 | return obj == null ? def : new Date(Long.valueOf(obj)); 57 | } 58 | 59 | public static Date getToday() { 60 | return DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH); 61 | } 62 | 63 | public static Date getDay(Date date) { 64 | return DateUtils.truncate(date, Calendar.DAY_OF_MONTH); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/APIRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api; 19 | 20 | import com.google.gson.Gson; 21 | 22 | import org.hibernate.HibernateException; 23 | import org.reflections.Reflections; 24 | 25 | import java.io.IOException; 26 | import java.io.PrintWriter; 27 | import java.text.ParseException; 28 | import java.util.HashMap; 29 | import java.util.Map; 30 | import java.util.Set; 31 | 32 | import javax.servlet.ServletException; 33 | import javax.servlet.annotation.WebServlet; 34 | import javax.servlet.http.HttpServlet; 35 | import javax.servlet.http.HttpServletRequest; 36 | import javax.servlet.http.HttpServletResponse; 37 | 38 | import love.sola.netsupport.enums.Access; 39 | import love.sola.netsupport.enums.Attribute; 40 | import love.sola.netsupport.pojo.Operator; 41 | import love.sola.netsupport.pojo.User; 42 | import love.sola.netsupport.session.WechatSession; 43 | import love.sola.netsupport.session.WxSession; 44 | import love.sola.netsupport.sql.SQLCore; 45 | 46 | /** 47 | * @author Sola {@literal } 48 | */ 49 | @WebServlet(name = "APIRouter", urlPatterns = "/api/*", loadOnStartup = 11) 50 | public class APIRouter extends HttpServlet { 51 | 52 | protected static Gson gson = SQLCore.gson; 53 | private Map nodes = new HashMap<>(); 54 | 55 | @Override 56 | public void init() throws ServletException { 57 | super.init(); 58 | try { 59 | Reflections reflections = new Reflections(getClass().getPackage().getName()); 60 | Set> set = reflections.getSubTypesOf(API.class); 61 | for (Class clz : set) { 62 | try { 63 | System.out.println("Loading API: " + clz.getName()); 64 | API obj = clz.newInstance(); 65 | System.out.println("Registered API: " + obj); 66 | nodes.put(obj.url, obj); 67 | } catch (InstantiationException | IllegalAccessException e) { 68 | e.printStackTrace(); 69 | } 70 | } 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | } 74 | System.out.println("Total " + nodes.size() + " API(s) loaded."); 75 | } 76 | 77 | @Override 78 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 79 | req.setCharacterEncoding("utf-8"); 80 | resp.setCharacterEncoding("utf-8"); 81 | resp.addHeader("Content-type", "application/json;charset=utf-8"); 82 | resp.addHeader("Access-Control-Allow-Origin", "*"); 83 | Object obj = null; 84 | try { 85 | API api = nodes.get(req.getPathInfo()); 86 | if (api == null) { 87 | resp.sendError(HttpServletResponse.SC_FORBIDDEN); 88 | return; 89 | } 90 | WxSession session = getSession(req); 91 | if (session == null) { 92 | obj = Error.UNAUTHORIZED; 93 | return; 94 | } 95 | if (api.authorize != null) { 96 | if (session.getAttribute(Attribute.AUTHORIZED) != api.authorize) { 97 | obj = Error.UNAUTHORIZED; 98 | return; 99 | } 100 | if (api.access == Access.USER) { 101 | User u = session.getAttribute(Attribute.USER); 102 | if (u == null) { 103 | obj = Error.UNAUTHORIZED; 104 | return; 105 | } 106 | } 107 | if (api.access < Access.USER) { 108 | Operator op = session.getAttribute(Attribute.OPERATOR); 109 | if (op == null) { 110 | obj = Error.UNAUTHORIZED; 111 | return; 112 | } 113 | if (op.getAccess() > api.access) { 114 | obj = Error.PERMISSION_DENIED; 115 | return; 116 | } 117 | } 118 | } 119 | obj = api.process(req, session); 120 | } catch (ParseException | NumberFormatException e) { 121 | obj = Error.ILLEGAL_PARAMETER; 122 | } catch (HibernateException e) { 123 | e.printStackTrace(); 124 | obj = Error.DATABASE_ERROR; 125 | } catch (Exception e) { 126 | e.printStackTrace(); 127 | obj = Error.INTERNAL_ERROR; 128 | } finally { 129 | if (!resp.isCommitted()) { 130 | try (PrintWriter out = resp.getWriter()) { 131 | out.println(gson.toJson(obj)); 132 | } 133 | } 134 | } 135 | } 136 | 137 | @Override 138 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 139 | doGet(req, resp); 140 | } 141 | 142 | @Override 143 | protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 144 | resp.addHeader("Access-Control-Allow-Method", "POST, GET, OPTIONS"); 145 | resp.addHeader("Access-Control-Allow-Origin", "*"); 146 | resp.setStatus(HttpServletResponse.SC_NO_CONTENT); 147 | } 148 | 149 | private static WxSession getSession(HttpServletRequest req) { 150 | String t = req.getParameter("token"); 151 | if (t == null || t.isEmpty()) return null; 152 | return WechatSession.get(t); 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/CheckSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api; 19 | 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | import javax.servlet.http.HttpServletRequest; 24 | 25 | import love.sola.netsupport.enums.Access; 26 | import love.sola.netsupport.enums.Attribute; 27 | import love.sola.netsupport.session.WxSession; 28 | 29 | /** 30 | * @author Sola {@literal } 31 | */ 32 | public class CheckSession extends API { 33 | 34 | public CheckSession() { 35 | url = "/checksession"; 36 | access = Access.GUEST; 37 | authorize = null; 38 | } 39 | 40 | @Override 41 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 42 | String more = req.getParameter("more"); 43 | Map result = new HashMap<>(); 44 | result.put(Attribute.AUTHORIZED, session.getAttribute(Attribute.AUTHORIZED)); 45 | if (more != null) { 46 | switch (more) { 47 | case "1": 48 | result.put(Attribute.USER, session.getAttribute(Attribute.USER)); 49 | result.put(Attribute.OPERATOR, session.getAttribute(Attribute.OPERATOR)); 50 | break; 51 | } 52 | } 53 | return result; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/Error.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api; 19 | 20 | import static love.sola.netsupport.config.Lang.lang; 21 | 22 | /** 23 | * @author Sola {@literal } 24 | */ 25 | public class Error { 26 | 27 | public static final Error ALREADY_SUBMITTED = new Error(1); 28 | public static final Object OK = new Object(); 29 | public static final Error PARAMETER_REQUIRED = new Error(-1); 30 | public static final Error ILLEGAL_PARAMETER = new Error(-2); 31 | // public static final Error REQUEST_FAILED = new Error(-3); REMOVED 32 | public static final Error LENGTH_LIMIT_EXCEEDED = new Error(-4); 33 | public static final Error INVALID_PARAMETER = new Error(-5); 34 | public static final Error USER_NOT_FOUND = new Error(-11); 35 | public static final Error TICKET_NOT_FOUND = new Error(-12); 36 | public static final Error OPERATOR_NOT_FOUND = new Error(-13); 37 | public static final Error UNAUTHORIZED = new Error(-20); 38 | public static final Error WRONG_PASSWORD = new Error(-22); 39 | public static final Error PERMISSION_DENIED = new Error(-24); 40 | public static final Error INTERNAL_ERROR = new Error(-90); 41 | public static final Error DATABASE_ERROR = new Error(-91); 42 | 43 | public int errCode; 44 | public String errMsg; 45 | 46 | private Error(int code) { 47 | this(code, lang("ERR_" + code)); 48 | } 49 | 50 | public Error(int errCode, String errMsg) { 51 | this.errCode = errCode; 52 | this.errMsg = errMsg; 53 | } 54 | 55 | public Error withMsg(String msg) { 56 | return new Error(errCode, msg); 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/Login.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api; 19 | 20 | import com.google.gson.Gson; 21 | 22 | import java.io.IOException; 23 | import java.io.PrintWriter; 24 | 25 | import javax.servlet.ServletException; 26 | import javax.servlet.annotation.WebServlet; 27 | import javax.servlet.http.HttpServlet; 28 | import javax.servlet.http.HttpServletRequest; 29 | import javax.servlet.http.HttpServletResponse; 30 | 31 | import love.sola.netsupport.enums.Access; 32 | import love.sola.netsupport.enums.Attribute; 33 | import love.sola.netsupport.pojo.Operator; 34 | import love.sola.netsupport.pojo.User; 35 | import love.sola.netsupport.session.WechatSession; 36 | import love.sola.netsupport.session.WxSession; 37 | import love.sola.netsupport.sql.SQLCore; 38 | import love.sola.netsupport.sql.TableOperator; 39 | import love.sola.netsupport.sql.TableUser; 40 | import love.sola.netsupport.util.Crypto; 41 | import love.sola.netsupport.wechat.Command; 42 | 43 | /** 44 | * @author Sola {@literal } 45 | */ 46 | 47 | @WebServlet(name = "Login", urlPatterns = "/api/admin/login", loadOnStartup = 12) 48 | public class Login extends HttpServlet { 49 | 50 | private Gson gson = SQLCore.gson; 51 | 52 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 53 | doGet(request, response); 54 | } 55 | 56 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 57 | request.setCharacterEncoding("utf-8"); 58 | response.setCharacterEncoding("utf-8"); 59 | response.addHeader("Content-type", "application/json;charset=utf-8"); 60 | response.addHeader("Access-Control-Allow-Origin", "*"); 61 | PrintWriter out = response.getWriter(); 62 | out.println(gson.toJson(login(request))); 63 | out.close(); 64 | } 65 | 66 | private Object login(HttpServletRequest request) { 67 | try { 68 | int oid = Integer.parseInt(request.getParameter("id")); 69 | String password = request.getParameter("pass"); 70 | boolean bypass = request.getParameter("bypass") != null; 71 | Operator op = TableOperator.get(oid); 72 | if (op == null) 73 | return Error.OPERATOR_NOT_FOUND; 74 | else if (op.getAccess() >= Access.NO_LOGIN) 75 | return Error.PERMISSION_DENIED; 76 | 77 | if (!Crypto.check(password, op.getPassword())) { 78 | return Error.WRONG_PASSWORD; 79 | } 80 | 81 | WxSession session = WechatSession.create(); 82 | if (bypass) { 83 | session.setAttribute(Attribute.AUTHORIZED, Command.fromId(Integer.parseInt(request.getParameter("bypass")))); 84 | } else { 85 | session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN); 86 | } 87 | 88 | session.setAttribute(Attribute.WECHAT, op.getWechat()); 89 | session.setAttribute(Attribute.OPERATOR, op); 90 | 91 | if (request.getParameter("bypassuser") != null) { 92 | User u = TableUser.getById(Long.parseLong(request.getParameter("bypassuser"))); 93 | session.setAttribute(Attribute.USER, u); 94 | session.setAttribute(Attribute.WECHAT, u.getWechatId()); 95 | } 96 | if (request.getParameter("bypasswechat") != null) { 97 | session.setAttribute(Attribute.WECHAT, request.getParameter("bypasswechat")); 98 | } 99 | return session.getId(); 100 | } catch (Exception e) { 101 | e.printStackTrace(); 102 | return Error.INTERNAL_ERROR; 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/manager/GetUser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.manager; 19 | 20 | import javax.servlet.http.HttpServletRequest; 21 | 22 | import love.sola.netsupport.api.API; 23 | import love.sola.netsupport.api.Error; 24 | import love.sola.netsupport.enums.Access; 25 | import love.sola.netsupport.pojo.User; 26 | import love.sola.netsupport.session.WxSession; 27 | import love.sola.netsupport.sql.TableUser; 28 | import love.sola.netsupport.wechat.Command; 29 | 30 | /** 31 | * @author Sola {@literal } 32 | */ 33 | public class GetUser extends API { 34 | 35 | public GetUser() { 36 | url = "/admin/getuser"; 37 | access = Access.LEADER; 38 | authorize = Command.LOGIN; 39 | } 40 | 41 | @Override 42 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 43 | String id = req.getParameter("id"); 44 | String name = req.getParameter("name"); 45 | if ((id == null || id.isEmpty()) && (name == null || name.isEmpty())) { 46 | return Error.PARAMETER_REQUIRED; 47 | } 48 | if (id != null) { 49 | try { 50 | User u = TableUser.getById(Long.parseLong(id)); 51 | if (u == null) 52 | return Error.USER_NOT_FOUND; 53 | else 54 | return u; 55 | } catch (NumberFormatException e) { 56 | return Error.ILLEGAL_PARAMETER; 57 | } 58 | } else { 59 | User u = TableUser.getByName(name); 60 | if (u == null) 61 | return Error.USER_NOT_FOUND; 62 | else 63 | return u; 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/manager/TicketPush.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.manager; 19 | 20 | import org.hibernate.Session; 21 | 22 | import javax.servlet.http.HttpServletRequest; 23 | 24 | import love.sola.netsupport.api.API; 25 | import love.sola.netsupport.api.Error; 26 | import love.sola.netsupport.config.Settings; 27 | import love.sola.netsupport.enums.Access; 28 | import love.sola.netsupport.enums.Attribute; 29 | import love.sola.netsupport.enums.Status; 30 | import love.sola.netsupport.pojo.Operator; 31 | import love.sola.netsupport.pojo.Ticket; 32 | import love.sola.netsupport.pojo.User; 33 | import love.sola.netsupport.session.WxSession; 34 | import love.sola.netsupport.sql.SQLCore; 35 | import love.sola.netsupport.util.Checker; 36 | import love.sola.netsupport.wechat.Command; 37 | 38 | /** 39 | * @author Sola {@literal } 40 | */ 41 | public class TicketPush extends API { 42 | 43 | public TicketPush() { 44 | url = "/admin/ticketpush"; 45 | access = Access.LEADER; 46 | authorize = Command.LOGIN; 47 | } 48 | 49 | @Override 50 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 51 | String uid = req.getParameter("uid"); 52 | String desc = req.getParameter("desc"); 53 | if (Checker.hasNull(uid, desc)) { 54 | return Error.PARAMETER_REQUIRED; 55 | } 56 | if (desc.length() > Settings.MAX_DESC_LENGTH) { 57 | return Error.LENGTH_LIMIT_EXCEEDED; 58 | } 59 | Operator op = session.getAttribute(Attribute.OPERATOR); 60 | try (Session s = SQLCore.sf.openSession()) { 61 | s.beginTransaction(); 62 | User u = s.get(User.class, Long.parseLong(uid)); 63 | if (u == null) { 64 | return Error.USER_NOT_FOUND; 65 | } 66 | Ticket t = new Ticket(u, desc, null, "Pushed By Admin", null, op, Status.UNCHECKED); 67 | s.save(t); 68 | s.getTransaction().commit(); 69 | return t; 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/root/DashBoard.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.root; 19 | 20 | import java.util.Set; 21 | 22 | import javax.servlet.http.HttpServletRequest; 23 | 24 | import love.sola.netsupport.api.API; 25 | import love.sola.netsupport.enums.Access; 26 | import love.sola.netsupport.session.WechatSession; 27 | import love.sola.netsupport.session.WxSession; 28 | import love.sola.netsupport.wechat.Command; 29 | 30 | /** 31 | * @author Sola {@literal } 32 | */ 33 | public class DashBoard extends API { 34 | 35 | public DashBoard() { 36 | url = "/root/dashboard"; 37 | access = Access.ROOT; 38 | authorize = Command.LOGIN; 39 | } 40 | 41 | @Override 42 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 43 | StringBuilder sb = new StringBuilder(); 44 | for (love.sola.netsupport.session.WxSession ws : WechatSession.list()) { 45 | sb.append("=====").append(ws.getId()).append("=====\n"); 46 | Set e = ws.getAttributeNames(); 47 | for (String key : e) { 48 | sb.append(key).append(": ").append(ws.getAttribute(key).toString()).append("\n"); 49 | } 50 | } 51 | return sb.toString(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/root/FlushCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.root; 19 | 20 | import javax.servlet.http.HttpServletRequest; 21 | 22 | import love.sola.netsupport.api.API; 23 | import love.sola.netsupport.api.Error; 24 | import love.sola.netsupport.enums.Access; 25 | import love.sola.netsupport.session.WxSession; 26 | import love.sola.netsupport.sql.TableUser; 27 | import love.sola.netsupport.wechat.Command; 28 | 29 | /** 30 | * @author Sola {@literal } 31 | */ 32 | public class FlushCache extends API { 33 | 34 | public FlushCache() { 35 | url = "/root/flushcache"; 36 | access = Access.ROOT; 37 | authorize = Command.LOGIN; 38 | } 39 | 40 | @Override 41 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 42 | TableUser.flushCache(); 43 | return Error.OK; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/root/SetPassword.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.root; 19 | 20 | import org.hibernate.Session; 21 | 22 | import javax.servlet.http.HttpServletRequest; 23 | 24 | import love.sola.netsupport.api.API; 25 | import love.sola.netsupport.api.Error; 26 | import love.sola.netsupport.enums.Access; 27 | import love.sola.netsupport.pojo.Operator; 28 | import love.sola.netsupport.session.WxSession; 29 | import love.sola.netsupport.sql.SQLCore; 30 | import love.sola.netsupport.util.Crypto; 31 | import love.sola.netsupport.wechat.Command; 32 | 33 | /** 34 | * @author Sola {@literal } 35 | */ 36 | public class SetPassword extends API { 37 | 38 | public SetPassword() { 39 | url = "/root/setpass"; 40 | access = Access.ROOT; 41 | authorize = Command.LOGIN; 42 | } 43 | 44 | @Override 45 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 46 | String id = req.getParameter("id"); 47 | String pass = req.getParameter("pass"); 48 | if (pass == null || pass.length() < 8) { 49 | return Error.INVALID_PARAMETER; 50 | } 51 | try (Session s = SQLCore.sf.openSession()) { 52 | s.beginTransaction(); 53 | Operator op = s.get(Operator.class, Integer.parseInt(id)); 54 | if (op == null) { 55 | return Error.OPERATOR_NOT_FOUND; 56 | } 57 | op.setPassword(Crypto.hash(pass)); 58 | s.update(op); 59 | s.getTransaction().commit(); 60 | return Error.OK; 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/stuff/TicketLog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.stuff; 19 | 20 | import love.sola.netsupport.api.API; 21 | import love.sola.netsupport.enums.Access; 22 | import love.sola.netsupport.pojo.Ticket; 23 | import love.sola.netsupport.pojo.User; 24 | import love.sola.netsupport.session.WxSession; 25 | import love.sola.netsupport.sql.SQLCore; 26 | import love.sola.netsupport.sql.TableTicket; 27 | import love.sola.netsupport.wechat.Command; 28 | import org.apache.commons.lang3.time.DateUtils; 29 | import org.hibernate.Session; 30 | import org.hibernate.envers.AuditReader; 31 | import org.hibernate.envers.query.AuditEntity; 32 | import org.hibernate.proxy.HibernateProxy; 33 | 34 | import javax.servlet.http.HttpServletRequest; 35 | import java.text.SimpleDateFormat; 36 | import java.util.Date; 37 | import java.util.List; 38 | 39 | /** 40 | * @author Sola {@literal } 41 | */ 42 | public class TicketLog extends API { 43 | 44 | public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); 45 | 46 | public TicketLog() { 47 | url = "/admin/ticketlog"; 48 | access = Access.MEMBER; 49 | authorize = Command.LOGIN; 50 | } 51 | 52 | @SuppressWarnings("unchecked") 53 | @Override 54 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 55 | int first; 56 | int limit; 57 | Date start; 58 | Date end; 59 | first = req.getParameter("first") == null ? 0 : Integer.parseInt(req.getParameter("first")); 60 | limit = req.getParameter("limit") == null ? 20 : Integer.parseInt(req.getParameter("limit")); 61 | start = req.getParameter("start") == null ? getToday() : dateFormat.parse(req.getParameter("start")); 62 | end = req.getParameter("end") == null ? getToday() : dateFormat.parse(req.getParameter("end")); 63 | end = DateUtils.addDays(end, 1); 64 | try (Session s = SQLCore.sf.openSession()) { 65 | AuditReader reader = TableTicket.getAuditReader(s); 66 | List resultList = reader.createQuery() 67 | .forRevisionsOfEntity(Ticket.class, false, true) 68 | .addOrder(AuditEntity.revisionNumber().desc()) 69 | .add(AuditEntity.revisionProperty("timestamp").between(start.getTime(), end.getTime())) 70 | .setFirstResult(first) 71 | .setMaxResults(limit) 72 | .getResultList(); 73 | return TableTicket.initializeTickets(resultList); 74 | } 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/stuff/TicketLookup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.stuff; 19 | 20 | import javax.servlet.http.HttpServletRequest; 21 | 22 | import love.sola.netsupport.api.API; 23 | import love.sola.netsupport.enums.Access; 24 | import love.sola.netsupport.enums.Attribute; 25 | import love.sola.netsupport.pojo.Operator; 26 | import love.sola.netsupport.session.WxSession; 27 | import love.sola.netsupport.sql.TableTicket; 28 | import love.sola.netsupport.wechat.Command; 29 | 30 | /** 31 | * @author Sola {@literal } 32 | */ 33 | public class TicketLookup extends API { 34 | 35 | public TicketLookup() { 36 | url = "/admin/ticketlookup"; 37 | access = Access.MEMBER; 38 | authorize = Command.LOGIN; 39 | } 40 | 41 | @Override 42 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 43 | Operator op = session.getAttribute(Attribute.OPERATOR); 44 | int block; 45 | if (req.getParameter("block") != null) { 46 | block = Integer.parseInt(req.getParameter("block")); 47 | } else { 48 | block = op.getBlock(); 49 | } 50 | return TableTicket.unsolvedByBlock(block); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/stuff/TicketTrack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.stuff; 19 | 20 | import javax.servlet.http.HttpServletRequest; 21 | 22 | import love.sola.netsupport.api.API; 23 | import love.sola.netsupport.api.Error; 24 | import love.sola.netsupport.enums.Access; 25 | import love.sola.netsupport.session.WxSession; 26 | import love.sola.netsupport.sql.TableTicket; 27 | import love.sola.netsupport.wechat.Command; 28 | 29 | /** 30 | * @author Sola {@literal } 31 | */ 32 | public class TicketTrack extends API { 33 | 34 | public TicketTrack() { 35 | url = "/admin/tickettrack"; 36 | access = Access.MEMBER; 37 | authorize = Command.LOGIN; 38 | } 39 | 40 | @Override 41 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 42 | String tid = req.getParameter("id"); 43 | if (tid == null) { 44 | return Error.PARAMETER_REQUIRED; 45 | } 46 | return TableTicket.track(Integer.parseInt(tid)); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/stuff/TicketUpdate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.stuff; 19 | 20 | import org.hibernate.Session; 21 | 22 | import java.util.Date; 23 | 24 | import javax.servlet.http.HttpServletRequest; 25 | 26 | import love.sola.netsupport.api.API; 27 | import love.sola.netsupport.api.Error; 28 | import love.sola.netsupport.enums.Access; 29 | import love.sola.netsupport.enums.Attribute; 30 | import love.sola.netsupport.pojo.Operator; 31 | import love.sola.netsupport.pojo.Ticket; 32 | import love.sola.netsupport.session.WxSession; 33 | import love.sola.netsupport.sql.SQLCore; 34 | import love.sola.netsupport.util.Checker; 35 | import love.sola.netsupport.wechat.Command; 36 | 37 | /** 38 | * @author Sola {@literal } 39 | */ 40 | public class TicketUpdate extends API { 41 | 42 | public TicketUpdate() { 43 | url = "/admin/ticketupdate"; 44 | access = Access.MEMBER; 45 | authorize = Command.LOGIN; 46 | } 47 | 48 | @Override 49 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 50 | String ticket = req.getParameter("ticket"); 51 | String remark = req.getParameter("remark"); 52 | String status = req.getParameter("status"); 53 | if (Checker.hasNull(ticket, remark, status)) return Error.PARAMETER_REQUIRED; 54 | try (Session s = SQLCore.sf.openSession()) { 55 | Operator op = session.getAttribute(Attribute.OPERATOR); 56 | Ticket t = s.get(Ticket.class, Integer.parseInt(ticket)); 57 | if (t == null) { 58 | return Error.TICKET_NOT_FOUND; 59 | } 60 | t.setOperator(op); 61 | t.setRemark(remark); 62 | t.setStatus(Integer.parseInt(status)); 63 | t.setUpdateTime(new Date()); 64 | s.beginTransaction(); 65 | s.update(t); 66 | s.getTransaction().commit(); 67 | return t; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/stuff/ToolsCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.stuff; 19 | 20 | import org.apache.commons.lang3.StringUtils; 21 | import org.apache.commons.lang3.time.DateUtils; 22 | import org.hibernate.Criteria; 23 | import org.hibernate.Session; 24 | import org.hibernate.criterion.Restrictions; 25 | import org.hibernate.type.IntegerType; 26 | import org.hibernate.type.Type; 27 | 28 | import java.util.Date; 29 | 30 | import javax.servlet.http.HttpServletRequest; 31 | 32 | import love.sola.netsupport.api.API; 33 | import love.sola.netsupport.api.Error; 34 | import love.sola.netsupport.enums.Access; 35 | import love.sola.netsupport.enums.Attribute; 36 | import love.sola.netsupport.pojo.Operator; 37 | import love.sola.netsupport.session.WxSession; 38 | import love.sola.netsupport.sql.SQLCore; 39 | import love.sola.netsupport.wechat.Command; 40 | 41 | /** 42 | * @author Sola 43 | */ 44 | public class ToolsCheck extends API { 45 | 46 | public ToolsCheck() { 47 | url = "/admin/toolscheck"; 48 | access = Access.MEMBER; 49 | authorize = Command.LOGIN; 50 | } 51 | 52 | @Override 53 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 54 | if (req.getMethod().equals("GET")) { 55 | return query(req, session); 56 | } else if (req.getMethod().equals("POST")) { 57 | return submit(req, session); 58 | } 59 | return null; 60 | } 61 | 62 | private Object submit(HttpServletRequest req, WxSession session) { 63 | Operator op = session.getAttribute(Attribute.OPERATOR); 64 | int status = Integer.valueOf(getParameterWithDefault(req.getParameter("status"), "0")); 65 | String remark = req.getParameter("remark"); 66 | if (status != 0 && StringUtils.isBlank(remark)) { 67 | return Error.PARAMETER_REQUIRED; 68 | } 69 | try (Session s = SQLCore.sf.openSession()) { 70 | s.beginTransaction(); 71 | s.save(new love.sola.netsupport.pojo.ToolsCheck( 72 | op, 73 | op.getBlock(), 74 | new Date(), 75 | status, 76 | remark 77 | )); 78 | s.getTransaction().commit(); 79 | return Error.OK; 80 | } 81 | } 82 | 83 | private Object query(HttpServletRequest req, WxSession session) { 84 | int status = Integer.valueOf(getParameterWithDefault(req.getParameter("status"), "0")); 85 | Date after = getDay(getParameterAsDate(req.getParameter("after"), getToday())); 86 | Date before = getDay(getParameterAsDate(req.getParameter("before"), getToday())); 87 | before = DateUtils.addDays(before, 1); 88 | int block = Integer.valueOf(getParameterWithDefault(req.getParameter("block"), "0")); 89 | try (Session s = SQLCore.sf.openSession()) { 90 | Criteria query = s.createCriteria(love.sola.netsupport.pojo.ToolsCheck.class); 91 | query.add( 92 | Restrictions.sqlRestriction( 93 | "{alias}.status & ? = ?", 94 | new Object[]{status, status}, 95 | new Type[]{IntegerType.INSTANCE, IntegerType.INSTANCE} 96 | ) 97 | ); 98 | query.add(Restrictions.between("checkTime", after, before)); 99 | if (block != 0) query.add(Restrictions.eq("block", block)); 100 | return query.list(); 101 | } 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/user/ProfileModify.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.user; 19 | 20 | import org.hibernate.exception.ConstraintViolationException; 21 | 22 | import javax.servlet.http.HttpServletRequest; 23 | 24 | import love.sola.netsupport.api.API; 25 | import love.sola.netsupport.api.Error; 26 | import love.sola.netsupport.enums.Access; 27 | import love.sola.netsupport.enums.Attribute; 28 | import love.sola.netsupport.enums.ISP; 29 | import love.sola.netsupport.pojo.User; 30 | import love.sola.netsupport.session.WxSession; 31 | import love.sola.netsupport.sql.TableUser; 32 | import love.sola.netsupport.wechat.Command; 33 | 34 | import static love.sola.netsupport.util.Checker.checkBlock; 35 | import static love.sola.netsupport.util.Checker.checkISP; 36 | import static love.sola.netsupport.util.Checker.checkNetAccount; 37 | import static love.sola.netsupport.util.Checker.checkPhoneNumber; 38 | import static love.sola.netsupport.util.Checker.checkRoom; 39 | 40 | /** 41 | * @author Sola {@literal } 42 | */ 43 | public class ProfileModify extends API { 44 | 45 | public ProfileModify() { 46 | url = "/profilemodify"; 47 | access = Access.USER; 48 | authorize = Command.PROFILE; 49 | } 50 | 51 | @Override 52 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 53 | User u = session.getAttribute(Attribute.USER); 54 | ISP isp = checkISP(req.getParameter("isp")); 55 | String netAccount = checkNetAccount(req.getParameter("username"), isp); 56 | int block = checkBlock(req.getParameter("block")); 57 | int room = checkRoom(req.getParameter("room"), block); 58 | long phone = checkPhoneNumber(req.getParameter("phone")); 59 | if (room == -1) 60 | return Error.INVALID_PARAMETER.withMsg("Invalid_Room"); 61 | if (phone == -1) 62 | return Error.INVALID_PARAMETER.withMsg("Invalid_Phone_Number"); 63 | if (netAccount == null) 64 | return Error.INVALID_PARAMETER.withMsg("Invalid_Account"); 65 | 66 | u.setIsp(isp); 67 | u.setNetAccount(netAccount); 68 | u.setBlock(block); 69 | u.setRoom(room); 70 | u.setPhone(phone); 71 | try { 72 | TableUser.update(u); 73 | } catch (ConstraintViolationException e) { 74 | String dupKey = e.getConstraintName(); 75 | return Error.INVALID_PARAMETER.withMsg("Duplicated_" + dupKey.toUpperCase()); 76 | } 77 | session.invalidate(); 78 | return Error.OK; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/user/Register.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.user; 19 | 20 | import org.hibernate.exception.ConstraintViolationException; 21 | 22 | import javax.servlet.http.HttpServletRequest; 23 | 24 | import love.sola.netsupport.api.API; 25 | import love.sola.netsupport.api.Error; 26 | import love.sola.netsupport.enums.Access; 27 | import love.sola.netsupport.enums.Attribute; 28 | import love.sola.netsupport.enums.ISP; 29 | import love.sola.netsupport.pojo.User; 30 | import love.sola.netsupport.session.WxSession; 31 | import love.sola.netsupport.sql.TableUser; 32 | import love.sola.netsupport.wechat.Command; 33 | 34 | import static love.sola.netsupport.util.Checker.checkBlock; 35 | import static love.sola.netsupport.util.Checker.checkISP; 36 | import static love.sola.netsupport.util.Checker.checkNetAccount; 37 | import static love.sola.netsupport.util.Checker.checkPhoneNumber; 38 | import static love.sola.netsupport.util.Checker.checkRoom; 39 | import static love.sola.netsupport.util.Checker.checkStudentId; 40 | 41 | /** 42 | * @author Sola {@literal } 43 | */ 44 | public class Register extends API { 45 | 46 | public Register() { 47 | url = "/register"; 48 | access = Access.GUEST; 49 | authorize = Command.REGISTER; 50 | } 51 | 52 | @Override 53 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 54 | String wechat = session.getAttribute(Attribute.WECHAT); 55 | if (wechat == null) { 56 | return Error.UNAUTHORIZED; 57 | } 58 | ISP isp = checkISP(req.getParameter("isp")); 59 | int block = checkBlock(req.getParameter("block")); 60 | return register( 61 | checkStudentId(req.getParameter("sid")), 62 | req.getParameter("name"), 63 | isp, 64 | checkNetAccount(req.getParameter("username"), isp), 65 | block, 66 | checkRoom(req.getParameter("room"), block), 67 | checkPhoneNumber(req.getParameter("phone")), 68 | wechat); 69 | } 70 | 71 | private Object register(long sid, String name, ISP isp, String netAccount, int block, int room, long phone, String wechat) { 72 | if (sid == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Student_Id"); 73 | if (name == null) return Error.INVALID_PARAMETER.withMsg("Invalid_Name"); 74 | if (isp == null) return Error.INVALID_PARAMETER.withMsg("Invalid_ISP"); 75 | if (netAccount == null) return Error.INVALID_PARAMETER.withMsg("Invalid_Account"); 76 | if (block == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Block"); 77 | if (room == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Room"); 78 | if (phone == -1) return Error.INVALID_PARAMETER.withMsg("Invalid_Phone_Number"); 79 | User user = TableUser.getById(sid); 80 | if (user == null) return Error.INVALID_PARAMETER.withMsg("Invalid_Student_Id"); 81 | if (!user.getName().equals(name)) return Error.INVALID_PARAMETER.withMsg("Invalid_Name"); 82 | if (user.getWechatId() != null) 83 | return Error.INVALID_PARAMETER.withMsg("User_Already_Registered"); 84 | user.setIsp(isp); 85 | user.setNetAccount(netAccount); 86 | user.setBlock(block); 87 | user.setRoom(room); 88 | user.setPhone(phone); 89 | user.setWechatId(wechat); 90 | try { 91 | TableUser.update(user); 92 | } catch (ConstraintViolationException e) { 93 | String dupKey = e.getConstraintName(); 94 | return Error.INVALID_PARAMETER.withMsg("Duplicated_" + dupKey.toUpperCase()); // PHONE ACCOUNT WECHAT 95 | } 96 | return Error.OK; 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/user/TicketQuery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.user; 19 | 20 | import org.hibernate.Criteria; 21 | import org.hibernate.Session; 22 | import org.hibernate.criterion.Order; 23 | import org.hibernate.criterion.Restrictions; 24 | 25 | import javax.servlet.http.HttpServletRequest; 26 | 27 | import love.sola.netsupport.api.API; 28 | import love.sola.netsupport.enums.Access; 29 | import love.sola.netsupport.enums.Attribute; 30 | import love.sola.netsupport.pojo.Ticket; 31 | import love.sola.netsupport.pojo.User; 32 | import love.sola.netsupport.session.WxSession; 33 | import love.sola.netsupport.sql.SQLCore; 34 | import love.sola.netsupport.wechat.Command; 35 | 36 | /** 37 | * @author Sola {@literal } 38 | */ 39 | public class TicketQuery extends API { 40 | 41 | public TicketQuery() { 42 | url = "/ticketquery"; 43 | access = Access.USER; 44 | authorize = Command.QUERY; 45 | } 46 | 47 | @Override 48 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 49 | try (Session s = SQLCore.sf.openSession()) { 50 | User u = session.getAttribute(Attribute.USER); 51 | Criteria c = s.createCriteria(Ticket.class); 52 | int first = req.getParameter("offset") == null ? 0 : Integer.parseInt(req.getParameter("offset")); 53 | int limit = req.getParameter("limit") == null ? 5 : Integer.parseInt(req.getParameter("limit")); 54 | c.setFirstResult(first); 55 | c.setMaxResults(limit); 56 | c.addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME)); 57 | c.add(Restrictions.eq(Ticket.PROPERTY_USER, u)); 58 | if (req.getParameter("status") != null) { 59 | c.add(Restrictions.eq(Ticket.PROPERTY_STATUS, Integer.parseInt(req.getParameter("status")))); 60 | } else if (req.getParameter("statusl") != null && req.getParameter("statush") != null) { 61 | c.add(Restrictions.between(Ticket.PROPERTY_STATUS, 62 | Integer.parseInt(req.getParameter("statusl")), 63 | Integer.parseInt(req.getParameter("statush")) 64 | )); 65 | } 66 | return c.list(); 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/api/user/TicketSubmit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.api.user; 19 | 20 | import org.hibernate.Session; 21 | 22 | import javax.servlet.http.HttpServletRequest; 23 | 24 | import love.sola.netsupport.api.API; 25 | import love.sola.netsupport.api.Error; 26 | import love.sola.netsupport.config.Settings; 27 | import love.sola.netsupport.enums.Access; 28 | import love.sola.netsupport.enums.Attribute; 29 | import love.sola.netsupport.pojo.Ticket; 30 | import love.sola.netsupport.pojo.User; 31 | import love.sola.netsupport.session.WxSession; 32 | import love.sola.netsupport.sql.SQLCore; 33 | import love.sola.netsupport.sql.TableTicket; 34 | import love.sola.netsupport.wechat.Command; 35 | 36 | /** 37 | * @author Sola {@literal } 38 | */ 39 | public class TicketSubmit extends API { 40 | 41 | public TicketSubmit() { 42 | url = "/ticketsubmit"; 43 | access = Access.USER; 44 | authorize = Command.SUBMIT; 45 | } 46 | 47 | @Override 48 | protected Object process(HttpServletRequest req, WxSession session) throws Exception { 49 | String desc = req.getParameter("desc"); 50 | if (desc == null || desc.isEmpty()) { 51 | return Error.PARAMETER_REQUIRED; 52 | } 53 | if (desc.length() > Settings.MAX_DESC_LENGTH) { 54 | return Error.LENGTH_LIMIT_EXCEEDED; 55 | } 56 | 57 | try (Session s = SQLCore.sf.openSession()) { 58 | User u = session.getAttribute(Attribute.USER); 59 | if (TableTicket.hasOpen(u)) { 60 | session.invalidate(); 61 | return Error.ALREADY_SUBMITTED; 62 | } 63 | Ticket t = new Ticket(); 64 | t.setUser(u); 65 | t.setDescription(desc); 66 | t.setStatus(0); 67 | s.beginTransaction(); 68 | s.save(t); 69 | s.getTransaction().commit(); 70 | session.invalidate(); 71 | return Error.OK; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/auth/OAuth2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.auth; 19 | 20 | import java.io.IOException; 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | import javax.servlet.AsyncContext; 25 | import javax.servlet.ServletException; 26 | import javax.servlet.annotation.WebServlet; 27 | import javax.servlet.http.HttpServlet; 28 | import javax.servlet.http.HttpServletRequest; 29 | import javax.servlet.http.HttpServletResponse; 30 | 31 | import love.sola.netsupport.session.WechatSession; 32 | import love.sola.netsupport.session.WxSession; 33 | import love.sola.netsupport.util.Checker; 34 | import love.sola.netsupport.wechat.WxMpServlet; 35 | import me.chanjar.weixin.mp.api.WxMpService; 36 | import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; 37 | 38 | /** 39 | * @author Sola {@literal } 40 | */ 41 | @WebServlet(name = "OAuth2", urlPatterns = "/oauth2/callback", loadOnStartup = 21, asyncSupported = true) 42 | public class OAuth2 extends HttpServlet { 43 | 44 | private static Map oAuth2HandlerMap = new HashMap<>(); 45 | 46 | /** 47 | * for {@link love.sola.netsupport.wechat.WxMpServlet#registerCommands} 48 | * 49 | * @param state the state key from open platform callback. 50 | * @param handler handler 51 | */ 52 | public static void registerOAuth2Handler(String state, OAuth2Handler handler) { 53 | oAuth2HandlerMap.put(state, handler); 54 | } 55 | 56 | @Override 57 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 58 | AsyncContext actx = req.startAsync(); 59 | String code = req.getParameter("code"); 60 | String state = req.getParameter("state"); 61 | if (Checker.hasNull(code, state)) { 62 | resp.sendError(HttpServletResponse.SC_FORBIDDEN); 63 | return; 64 | } 65 | OAuth2Handler handler = oAuth2HandlerMap.get(state); 66 | if (handler == null) { 67 | resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); 68 | return; 69 | } 70 | actx.start(() -> { 71 | try { 72 | WxMpService wxMpService = WxMpServlet.instance.wxMpService; 73 | WxMpOAuth2AccessToken token = wxMpService.oauth2getAccessToken(code); 74 | String wechat = token.getOpenId(); 75 | WxSession session = WechatSession.create(); 76 | handler.onOAuth2(actx, (HttpServletResponse) actx.getResponse(), wechat, session); 77 | actx.complete(); 78 | } catch (Exception e) { 79 | e.printStackTrace(); 80 | } 81 | }); 82 | 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/auth/OAuth2Handler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.auth; 19 | 20 | import javax.servlet.AsyncContext; 21 | import javax.servlet.http.HttpServletResponse; 22 | 23 | import love.sola.netsupport.session.WxSession; 24 | 25 | /** 26 | * @author Sola {@literal } 27 | */ 28 | public interface OAuth2Handler { 29 | 30 | void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/config/Lang.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.config; 19 | 20 | import org.yaml.snakeyaml.Yaml; 21 | 22 | import java.io.InputStream; 23 | import java.text.MessageFormat; 24 | import java.util.HashMap; 25 | import java.util.Map; 26 | 27 | /** 28 | * @author Sola {@literal } 29 | */ 30 | public class Lang { 31 | 32 | public static Map messages; 33 | public static Map format_cache = new HashMap<>(32); 34 | 35 | static { 36 | InputStream in = Lang.class.getClassLoader().getResourceAsStream("lang.yml"); 37 | //noinspection unchecked 38 | messages = new Yaml().loadAs(in, Map.class); 39 | } 40 | 41 | public static String lang(String key) { 42 | String value = messages.get(key); 43 | return value == null ? "!!" + key + "!!" : value; 44 | } 45 | 46 | public static String format(String key, Object... args) { 47 | MessageFormat cache = format_cache.get(key); 48 | if (cache != null) { 49 | return cache.format(args); 50 | } else { 51 | cache = new MessageFormat(lang(key)); 52 | format_cache.put(key, cache); 53 | return cache.format(args); 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/config/Settings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.config; 19 | 20 | import love.sola.netsupport.sql.TableConfig; 21 | 22 | /** 23 | * @author Sola {@literal } 24 | */ 25 | public class Settings { 26 | 27 | public static final int MAX_DESC_LENGTH = 255; 28 | 29 | public static Settings I; 30 | 31 | static { 32 | I = TableConfig.getSettings(); 33 | } 34 | 35 | public String Wechat_AppId; 36 | public String Wechat_Secret; 37 | public String Wechat_Token; 38 | public String Wechat_AesKey; 39 | 40 | public int Check_Spam_Cache_Expire_Time; 41 | public int Check_Spam_Interval; 42 | 43 | public int User_Session_Max_Inactive; 44 | public int User_Wechat_Cache_Expire_Time; 45 | 46 | //No arg constructor for Yaml.loadAs 47 | public Settings() { 48 | I = this; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "Settings{" + 54 | "Wechat_AppId='" + Wechat_AppId + '\'' + 55 | ", Wechat_Secret='" + Wechat_Secret + '\'' + 56 | ", Wechat_Token='" + Wechat_Token + '\'' + 57 | ", Wechat_AesKey='" + Wechat_AesKey + '\'' + 58 | ", Check_Spam_Cache_Expire_Time=" + Check_Spam_Cache_Expire_Time + 59 | ", Check_Spam_Interval=" + Check_Spam_Interval + 60 | ", User_Session_Max_Inactive=" + User_Session_Max_Inactive + 61 | ", User_Wechat_Cache_Expire_Time=" + User_Wechat_Cache_Expire_Time + 62 | '}'; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/enums/Access.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.enums; 19 | 20 | import java.lang.reflect.Field; 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | import static love.sola.netsupport.config.Lang.lang; 25 | 26 | /** 27 | * @author Sola {@literal } 28 | */ 29 | public class Access { 30 | 31 | public static final int GOD_MODE = -1; 32 | public static final int ROOT = 0; 33 | public static final int MANAGER = 1; 34 | public static final int CO_MANAGER = 2; 35 | public static final int LEADER = 3; 36 | public static final int CO_LEADER = 4; 37 | public static final int ELITE = 5; 38 | public static final int ELDER = 6; 39 | public static final int MEMBER = 7; 40 | public static final int PRE_MEMBER = 8; 41 | public static final int NO_LOGIN = 9; 42 | public static final int USER = 10; 43 | public static final int GUEST = 11; 44 | 45 | public static final Map inverseMap = new HashMap<>(); 46 | 47 | static { 48 | System.out.println("Loading Access..."); 49 | for (Field field : Access.class.getDeclaredFields()) { 50 | if (field.getType().isAssignableFrom(Integer.TYPE)) { 51 | try { 52 | inverseMap.put((Integer) field.get(null), field.getName()); 53 | } catch (IllegalAccessException e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | } 58 | } 59 | 60 | public static String getLocalized(int access) { 61 | if (inverseMap.containsKey(access)) { 62 | return lang("ACCESS_" + inverseMap.get(access)); 63 | } 64 | return null; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/enums/Attribute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.enums; 19 | 20 | /** 21 | * @author Sola {@literal } 22 | */ 23 | public class Attribute { 24 | 25 | public static final String AUTHORIZED = "authorized"; 26 | public static final String WECHAT = "wechat"; 27 | public static final String OPERATOR = "operator"; 28 | public static final String USER = "user"; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/enums/Block.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.enums; 19 | 20 | import java.lang.reflect.Field; 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | /** 25 | * @author Sola {@literal } 26 | */ 27 | public class Block { 28 | 29 | public static final int QT_18 = 10; 30 | public static final int QT_19 = 11; 31 | public static final int QT_16 = 12; 32 | public static final int QT_17 = 13; 33 | public static final int BM_7 = 20; 34 | public static final int BM_8 = 21; 35 | public static final int BM_9 = 22; 36 | public static final int BM_10 = 23; 37 | public static final int BM_11 = 24; 38 | public static final int DM_12 = 30; 39 | public static final int DM_13 = 31; 40 | public static final int DM_14 = 32; 41 | public static final int DM_15 = 33; 42 | public static final int DM_20 = 34; 43 | public static final int DM_21 = 35; 44 | public static final int XH_A = 40; 45 | public static final int XH_B = 41; 46 | public static final int XH_C = 42; 47 | public static final int XH_D = 43; 48 | public static final int FX_1 = 50; 49 | public static final int FX_2 = 51; 50 | public static final int FX_3 = 52; 51 | public static final int FX_4 = 53; 52 | public static final int FX_5 = 54; 53 | public static final int FX_6 = 55; 54 | public static final int BS_1 = 60; 55 | public static final int BS_2 = 61; 56 | public static final int BS_3 = 62; 57 | public static final int BS_4 = 63; 58 | public static final int BS_5 = 64; 59 | public static final int BS_6 = 65; 60 | public static final int BS_7 = 66; 61 | public static final int BS_8 = 67; 62 | public static final int BS_9 = 68; 63 | public static final int ZH = 80; 64 | 65 | public static final Map inverseMap = new HashMap<>(); 66 | 67 | static { 68 | System.out.println("Loading Blocks..."); 69 | for (Field field : Block.class.getDeclaredFields()) { 70 | if (field.getType().isAssignableFrom(Integer.TYPE)) { 71 | try { 72 | inverseMap.put((Integer) field.get(null), field.getName()); 73 | } catch (IllegalAccessException e) { 74 | e.printStackTrace(); 75 | } 76 | } 77 | } 78 | } 79 | 80 | private static final int[][] AVAILABLE = new int[100][0]; 81 | 82 | static { 83 | // @formatter:off 84 | // -------------------------------------------- // 85 | // THANKS DATA PROVIDED BY Lai Juncheng 86 | // -------------------------------------------- // 87 | // UPDATE 2018:BS was destroyed.Update by HTroy 88 | // -------------------------------------------- // 89 | AVAILABLE[FX_1] = new int[]{108, 208, 308, 408, 508}; 90 | AVAILABLE[FX_2] = new int[]{110, 210, 310, 410, 510, 610}; 91 | AVAILABLE[FX_3] = new int[]{110, 210, 310, 410, 510, 610}; 92 | AVAILABLE[FX_4] = new int[]{110, 210, 310, 410, 510, 610, 710}; 93 | AVAILABLE[FX_5] = new int[]{108, 208, 308, 408, 508, 608, 708}; 94 | AVAILABLE[BM_7] = new int[]{100, 216, 317, 417, 517, 617, 717}; 95 | AVAILABLE[BM_8] = new int[]{100, 221, 321, 421, 521, 621, 721}; 96 | AVAILABLE[BM_9] = new int[]{100, 221, 321, 421, 521, 621}; 97 | AVAILABLE[BM_10] = new int[]{111, 239, 354, 454, 564, 664, 764, 864}; 98 | AVAILABLE[BM_11] = new int[]{100, 213, 321, 421, 521, 621, 721, 821}; 99 | AVAILABLE[DM_12] = new int[]{119, 221, 321, 421, 521, 621, 720}; 100 | AVAILABLE[DM_13] = new int[]{120, 222, 322, 422, 522, 622, 722}; 101 | AVAILABLE[DM_14] = new int[]{100, 230, 330, 430, 530, 630, 730}; 102 | AVAILABLE[DM_15] = new int[]{119, 219, 319, 419, 519, 619}; 103 | AVAILABLE[QT_16] = new int[]{154, 257, 357, 457, 557, 657, 757}; 104 | AVAILABLE[QT_17] = new int[]{154, 257, 357, 457, 557, 657, 757}; 105 | AVAILABLE[QT_18] = new int[]{139, 239, 339, 439, 539, 639, 739}; 106 | AVAILABLE[QT_19] = new int[]{100, 200, 332, 432, 532, 632, 732}; 107 | AVAILABLE[DM_20] = new int[]{109, 209, 309, 409, 509, 609, 709}; 108 | AVAILABLE[DM_21] = new int[]{109, 209, 309, 409, 509, 609, 709}; 109 | AVAILABLE[XH_A] = new int[]{129, 231, 331, 431, 531, 631, 731, 831, 931, 1031, 1131, 1231}; 110 | AVAILABLE[XH_B] = new int[]{129, 229, 329, 429, 529, 629, 729, 829, 929, 1029, 1129, 1229}; 111 | AVAILABLE[XH_C] = new int[]{126, 226, 326, 426, 526, 626, 726, 826, 926, 1026, 1126, 1226}; 112 | AVAILABLE[XH_D] = new int[]{128, 228, 328, 428, 528, 628, 728, 828, 928, 1028, 1128, 1228}; 113 | AVAILABLE[FX_6] = new int[0]; 114 | AVAILABLE[BS_1] = new int[0]; 115 | AVAILABLE[BS_2] = new int[0]; 116 | AVAILABLE[BS_3] = new int[0]; 117 | AVAILABLE[BS_4] = new int[0]; 118 | AVAILABLE[BS_5] = new int[0]; 119 | AVAILABLE[BS_6] = new int[0]; 120 | AVAILABLE[BS_7] = new int[0]; 121 | AVAILABLE[BS_8] = new int[0]; 122 | AVAILABLE[BS_9] = new int[0]; 123 | AVAILABLE[ZH] = new int[]{199, 299, 399, 499, 599, 699, 799, 899, 999, 1099, 1199, 1299, 1399, 1499}; 124 | // @formatter:on 125 | } 126 | 127 | public static boolean checkRoom(int block, int room) { 128 | int floor = room / 100; 129 | if (floor == 0 || room % 100 == 0) return false; 130 | if (block < 0 || block >= AVAILABLE.length) return false; 131 | if (AVAILABLE[block].length < floor) return false; 132 | return room <= AVAILABLE[block][floor - 1]; 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/enums/ISP.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.enums; 19 | 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | import static love.sola.netsupport.config.Lang.lang; 24 | 25 | /** 26 | * @author Sola {@literal } 27 | */ 28 | public enum ISP { 29 | 30 | TELECOM(1, "^1[3|4|5|6|7|8|9][0-9]{9}$"), 31 | UNICOM(2, "^\\w+([-+.]\\w+)*@16900\\.gd"), 32 | CHINAMOBILE(3, "^1[3|4|5|6|7|8|9][0-9]{9}@139\\.gd$"), 33 | OTHER(4, ".*"), 34 | ; 35 | 36 | private static final Map NAME_MAP = new HashMap<>(); 37 | private static final Map ID_MAP = new HashMap<>(); 38 | 39 | static { 40 | for (ISP type : values()) { 41 | if (type.name != null) { 42 | NAME_MAP.put(type.name.toLowerCase(), type); 43 | } 44 | if (type.id > 0) { 45 | ID_MAP.put(type.id, type); 46 | } 47 | } 48 | } 49 | 50 | public final int id; 51 | public final String name; 52 | public final String accountRegex; 53 | 54 | ISP(int id, String accountRegex) { 55 | this.id = id; 56 | this.name = lang("ISP_" + name()); 57 | this.accountRegex = accountRegex; 58 | } 59 | 60 | public static ISP fromName(String name) { 61 | if (name == null) { 62 | return null; 63 | } 64 | return NAME_MAP.get(name.toLowerCase()); 65 | } 66 | 67 | public static ISP fromId(int id) { 68 | return ID_MAP.get(id); 69 | } 70 | 71 | @Override 72 | public String toString() { 73 | return name; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/enums/ISPConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.enums; 19 | 20 | import javax.persistence.AttributeConverter; 21 | import javax.persistence.Converter; 22 | 23 | /** 24 | * @author Sola {@literal } 25 | */ 26 | @Converter 27 | public class ISPConverter implements AttributeConverter { 28 | 29 | @Override 30 | public Integer convertToDatabaseColumn(ISP attribute) { 31 | if (attribute == null) { 32 | return null; 33 | } 34 | return attribute.id; 35 | } 36 | 37 | @Override 38 | public ISP convertToEntityAttribute(Integer dbData) { 39 | if (dbData == null) { 40 | return null; 41 | } 42 | return ISP.fromId(dbData); 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/enums/Status.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.enums; 19 | 20 | import java.lang.reflect.Field; 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | import static love.sola.netsupport.config.Lang.lang; 25 | 26 | /** 27 | * @author Sola {@literal } 28 | */ 29 | public class Status { 30 | 31 | public static final int UNCHECKED = 0; 32 | public static final int ARRANGED = 1; 33 | public static final int PUTOFF = 2; 34 | public static final int REPORTED = 4; 35 | public static final int ISP_HANDLED = 7; 36 | public static final int SOLVED = 9; 37 | 38 | public static final Map inverseMap = new HashMap<>(); 39 | 40 | static { 41 | System.out.println("Loading Status..."); 42 | for (Field field : Status.class.getDeclaredFields()) { 43 | if (field.getType().isAssignableFrom(Integer.TYPE)) { 44 | try { 45 | inverseMap.put((Integer) field.get(null), field.getName()); 46 | } catch (IllegalAccessException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | } 51 | } 52 | 53 | public static String getLocalized(int status) { 54 | if (inverseMap.containsKey(status)) { 55 | return lang("STATUS_" + inverseMap.get(status)); 56 | } 57 | return null; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/pojo/Operator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.pojo; 19 | 20 | import com.google.gson.annotations.Expose; 21 | 22 | import javax.persistence.Column; 23 | import javax.persistence.Entity; 24 | import javax.persistence.Id; 25 | import javax.persistence.Table; 26 | 27 | /** 28 | * @author Sola {@literal } 29 | */ 30 | @Entity 31 | @Table(name = "operators") 32 | public class Operator { 33 | 34 | public static final String PROPERTY_WECHAT = "wechat"; 35 | 36 | //System Accounts 37 | public static Operator USER_SELF; 38 | public static Operator ADMIN; 39 | 40 | @Id 41 | @Column(name = "id", nullable = false, insertable = false, updatable = false) 42 | private Integer id; 43 | @Column(name = "name", nullable = false, insertable = false, updatable = false) 44 | private String name; 45 | @Column(name = "access", nullable = false, insertable = false, updatable = false) 46 | private Integer access; 47 | @Column(name = "wechat", insertable = false, updatable = false) 48 | @Expose(serialize = false) 49 | private String wechat; 50 | private Integer block; 51 | private Integer week; 52 | @Expose(serialize = false) 53 | private String password; 54 | 55 | public Operator(Integer id, String name, Integer access, String wechat, Integer block, Integer week, String password) { 56 | this.id = id; 57 | this.name = name; 58 | this.access = access; 59 | this.wechat = wechat; 60 | this.block = block; 61 | this.week = week; 62 | this.password = password; 63 | } 64 | 65 | public Operator() { 66 | } 67 | 68 | public Integer getId() { 69 | return id; 70 | } 71 | 72 | public void setId(Integer id) { 73 | this.id = id; 74 | } 75 | 76 | public String getName() { 77 | return name; 78 | } 79 | 80 | public void setName(String name) { 81 | this.name = name; 82 | } 83 | 84 | public Integer getAccess() { 85 | return access; 86 | } 87 | 88 | public void setAccess(Integer access) { 89 | this.access = access; 90 | } 91 | 92 | public String getWechat() { 93 | return wechat; 94 | } 95 | 96 | public void setWechat(String wechat) { 97 | this.wechat = wechat; 98 | } 99 | 100 | public Integer getBlock() { 101 | return block; 102 | } 103 | 104 | public void setBlock(Integer block) { 105 | this.block = block; 106 | } 107 | 108 | public Integer getWeek() { 109 | return week; 110 | } 111 | 112 | public void setWeek(Integer week) { 113 | this.week = week; 114 | } 115 | 116 | public String getPassword() { 117 | return password; 118 | } 119 | 120 | public void setPassword(String password) { 121 | this.password = password; 122 | } 123 | 124 | @Override 125 | public String toString() { 126 | return "Operator{" + 127 | "id=" + id + 128 | ", name='" + name + '\'' + 129 | ", access=" + access + 130 | ", wechat='" + wechat + '\'' + 131 | ", block=" + block + 132 | ", week=" + week + 133 | '}'; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/pojo/Ticket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.pojo; 19 | 20 | import org.hibernate.envers.Audited; 21 | import org.hibernate.envers.RelationTargetAuditMode; 22 | 23 | import java.util.Date; 24 | 25 | import javax.persistence.Column; 26 | import javax.persistence.Entity; 27 | import javax.persistence.GeneratedValue; 28 | import javax.persistence.GenerationType; 29 | import javax.persistence.Id; 30 | import javax.persistence.JoinColumn; 31 | import javax.persistence.ManyToOne; 32 | import javax.persistence.Table; 33 | 34 | import love.sola.netsupport.sql.TableTicket; 35 | 36 | /** 37 | * @author Sola {@literal } 38 | */ 39 | @Entity 40 | @Table(name = "tickets") 41 | @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) 42 | public class Ticket { 43 | 44 | public static final String PROPERTY_USER = "user"; 45 | public static final String PROPERTY_STATUS = "status"; 46 | public static final String PROPERTY_SUBMIT_TIME = "submitTime"; 47 | 48 | @Id 49 | @GeneratedValue(strategy = GenerationType.IDENTITY) 50 | private Integer id; 51 | @ManyToOne(optional = false) 52 | @JoinColumn(name = TableTicket.COLUMN_SID) 53 | private User user; 54 | private String description; 55 | @Column(name = TableTicket.COLUMN_SUBMIT_TIME, insertable = false, updatable = false) 56 | private Date submitTime; 57 | private String remark; 58 | private Date updateTime; 59 | @ManyToOne 60 | @JoinColumn(name = TableTicket.COLUMN_OPSID) 61 | private Operator operator; 62 | private Integer status; 63 | 64 | public Ticket() { 65 | } 66 | 67 | public Ticket(User user, String description, Date submitTime, String remark, Date updateTime, Operator operator, Integer status) { 68 | this.user = user; 69 | this.description = description; 70 | this.submitTime = submitTime; 71 | this.remark = remark; 72 | this.updateTime = updateTime; 73 | this.operator = operator; 74 | this.status = status; 75 | } 76 | 77 | public Integer getId() { 78 | return id; 79 | } 80 | 81 | public void setId(Integer id) { 82 | this.id = id; 83 | } 84 | 85 | public User getUser() { 86 | return user; 87 | } 88 | 89 | public void setUser(User user) { 90 | this.user = user; 91 | } 92 | 93 | public String getDescription() { 94 | return description; 95 | } 96 | 97 | public void setDescription(String description) { 98 | this.description = description; 99 | } 100 | 101 | public Date getSubmitTime() { 102 | return submitTime; 103 | } 104 | 105 | public void setSubmitTime(Date submitTime) { 106 | this.submitTime = submitTime; 107 | } 108 | 109 | public String getRemark() { 110 | return remark; 111 | } 112 | 113 | public void setRemark(String remark) { 114 | this.remark = remark; 115 | } 116 | 117 | public Date getUpdateTime() { 118 | return updateTime; 119 | } 120 | 121 | public void setUpdateTime(Date updateTime) { 122 | this.updateTime = updateTime; 123 | } 124 | 125 | public Operator getOperator() { 126 | return operator; 127 | } 128 | 129 | public void setOperator(Operator operator) { 130 | this.operator = operator; 131 | } 132 | 133 | public Integer getStatus() { 134 | return status; 135 | } 136 | 137 | public void setStatus(Integer status) { 138 | this.status = status; 139 | } 140 | 141 | @Override 142 | public String toString() { 143 | return "Ticket{" + 144 | "id=" + id + 145 | ", user=" + user + 146 | ", description='" + description + '\'' + 147 | ", submitTime=" + submitTime + 148 | ", remark='" + remark + '\'' + 149 | ", updateTime=" + updateTime + 150 | ", operator=" + operator + 151 | ", status=" + status + 152 | '}'; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/pojo/ToolsCheck.java: -------------------------------------------------------------------------------- 1 | package love.sola.netsupport.pojo; 2 | 3 | import org.hibernate.annotations.ColumnDefault; 4 | import org.hibernate.annotations.DynamicInsert; 5 | 6 | import java.util.Date; 7 | 8 | import javax.persistence.Column; 9 | import javax.persistence.Entity; 10 | import javax.persistence.GeneratedValue; 11 | import javax.persistence.GenerationType; 12 | import javax.persistence.Id; 13 | import javax.persistence.Index; 14 | import javax.persistence.JoinColumn; 15 | import javax.persistence.ManyToOne; 16 | import javax.persistence.Table; 17 | 18 | /** 19 | * @author Sola {@literal } 20 | */ 21 | @Entity 22 | @Table(name = "toolschk", indexes = { 23 | @Index(columnList = "block,chktime,status"), 24 | @Index(columnList = "chktime,status") 25 | }) 26 | @DynamicInsert 27 | public class ToolsCheck { 28 | 29 | @Id 30 | @GeneratedValue(strategy = GenerationType.IDENTITY) 31 | private Integer id; 32 | @ManyToOne(optional = false) 33 | @JoinColumn(name = "opsid", nullable = false) 34 | private Operator operator; 35 | @Column(nullable = false) 36 | private Integer block; 37 | @Column(name = "chktime", nullable = false) 38 | private Date checkTime = new Date(); 39 | @ColumnDefault("0") 40 | private Integer status = 0; 41 | private String remark; 42 | 43 | 44 | public ToolsCheck() { 45 | } 46 | 47 | public ToolsCheck(Operator operator, Integer block, Date checkTime, Integer status, String remark) { 48 | this.operator = operator; 49 | this.block = block; 50 | this.checkTime = checkTime; 51 | this.status = status; 52 | this.remark = remark; 53 | } 54 | 55 | public Integer getId() { 56 | return id; 57 | } 58 | 59 | public void setId(Integer id) { 60 | this.id = id; 61 | } 62 | 63 | public Operator getOperator() { 64 | return operator; 65 | } 66 | 67 | public void setOperator(Operator operator) { 68 | this.operator = operator; 69 | } 70 | 71 | public Integer getBlock() { 72 | return block; 73 | } 74 | 75 | public void setBlock(Integer block) { 76 | this.block = block; 77 | } 78 | 79 | public Date getCheckTime() { 80 | return checkTime; 81 | } 82 | 83 | public void setCheckTime(Date checkTime) { 84 | this.checkTime = checkTime; 85 | } 86 | 87 | public Integer getStatus() { 88 | return status; 89 | } 90 | 91 | public void setStatus(Integer status) { 92 | this.status = status; 93 | } 94 | 95 | public String getRemark() { 96 | return remark; 97 | } 98 | 99 | public void setRemark(String remark) { 100 | this.remark = remark; 101 | } 102 | 103 | @Override 104 | public String toString() { 105 | return "ToolsCheck{" + 106 | "id=" + id + 107 | ", operator=" + operator + 108 | ", block=" + block + 109 | ", checkTime=" + checkTime + 110 | ", status=" + status + 111 | ", remark='" + remark + '\'' + 112 | '}'; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/pojo/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.pojo; 19 | 20 | import com.google.gson.annotations.Expose; 21 | 22 | import javax.persistence.Column; 23 | import javax.persistence.Convert; 24 | import javax.persistence.Entity; 25 | import javax.persistence.Id; 26 | import javax.persistence.Table; 27 | 28 | import love.sola.netsupport.enums.ISP; 29 | import love.sola.netsupport.enums.ISPConverter; 30 | 31 | /** 32 | * @author Sola {@literal } 33 | */ 34 | @Entity 35 | @Table(name = "users") 36 | public class User { 37 | 38 | //System Accounts 39 | public static User OFFICIAL_CHINA_UNICOM_XH; 40 | public static User OFFICIAL_CHINA_MOBILE_XH; 41 | public static User OFFICIAL_CHINA_MOBILE_FX; 42 | 43 | public static final String PROPERTY_NAME = "name"; 44 | public static final String PROPERTY_WECHAT = "wechatId"; 45 | public static final String PROPERTY_BLOCK = "block"; 46 | 47 | @Id 48 | @Column(name = "id", updatable = false, nullable = false) 49 | private Long id; 50 | @Column(name = "name", updatable = false, nullable = false) 51 | private String name; 52 | @Convert(converter = ISPConverter.class) 53 | private ISP isp; 54 | @Column(name = "netaccount") 55 | private String netAccount; 56 | @Expose(serialize = false) 57 | @Column(name = "wechat") 58 | private String wechatId; 59 | private Integer block; 60 | private Integer room; 61 | private Long phone; 62 | 63 | public User() { 64 | } 65 | 66 | public User(Long id, String name, ISP isp, String netAccount, String wechatId, Integer block, Integer room, Long phone) { 67 | this.id = id; 68 | this.name = name; 69 | this.isp = isp; 70 | this.netAccount = netAccount; 71 | this.wechatId = wechatId; 72 | this.block = block; 73 | this.room = room; 74 | this.phone = phone; 75 | } 76 | 77 | public Long getId() { 78 | return id; 79 | } 80 | 81 | public void setId(Long id) { 82 | this.id = id; 83 | } 84 | 85 | public String getName() { 86 | return name; 87 | } 88 | 89 | public void setName(String name) { 90 | this.name = name; 91 | } 92 | 93 | public ISP getIsp() { 94 | return isp; 95 | } 96 | 97 | public void setIsp(ISP isp) { 98 | this.isp = isp; 99 | } 100 | 101 | public String getNetAccount() { 102 | return netAccount; 103 | } 104 | 105 | public void setNetAccount(String netAccount) { 106 | this.netAccount = netAccount; 107 | } 108 | 109 | public String getWechatId() { 110 | return wechatId; 111 | } 112 | 113 | public void setWechatId(String wechatId) { 114 | this.wechatId = wechatId; 115 | } 116 | 117 | public Integer getBlock() { 118 | return block; 119 | } 120 | 121 | public void setBlock(Integer block) { 122 | this.block = block; 123 | } 124 | 125 | public Integer getRoom() { 126 | return room; 127 | } 128 | 129 | public void setRoom(Integer room) { 130 | this.room = room; 131 | } 132 | 133 | public Long getPhone() { 134 | return phone; 135 | } 136 | 137 | public void setPhone(Long phone) { 138 | this.phone = phone; 139 | } 140 | 141 | @Override 142 | public String toString() { 143 | return "User{" + 144 | "id=" + id + 145 | ", name='" + name + '\'' + 146 | ", isp=" + isp + 147 | ", netAccount='" + netAccount + '\'' + 148 | ", wechatId='" + wechatId + '\'' + 149 | ", block=" + block + 150 | ", room=" + room + 151 | ", phone=" + phone + 152 | '}'; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/session/MapSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | /* 19 | * Copyright 2002-2015 the original author or authors. 20 | * 21 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 22 | * use this file except in compliance with the License. You may obtain a copy of 23 | * the License at 24 | * 25 | * http://www.apache.org/licenses/LICENSE-2.0 26 | * 27 | * Unless required by applicable law or agreed to in writing, software 28 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 29 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 30 | * License for the specific language governing permissions and limitations under 31 | * the License. 32 | */ 33 | package love.sola.netsupport.session; 34 | 35 | import java.io.Serializable; 36 | import java.util.HashMap; 37 | import java.util.Map; 38 | import java.util.Objects; 39 | import java.util.Set; 40 | import java.util.UUID; 41 | 42 | /** 43 | * @author Sola {@literal } 44 | */ 45 | public final class MapSession implements WxSession, Serializable { 46 | 47 | private final String id; 48 | private Map sessionAttrs = new HashMap(); 49 | private long creationTime = System.currentTimeMillis(); 50 | private long lastAccessedTime = creationTime; 51 | private boolean invalidated = false; 52 | 53 | /** 54 | * Creates a new instance with a secure randomly generated identifier. 55 | */ 56 | public MapSession() { 57 | this(UUID.randomUUID().toString()); 58 | } 59 | 60 | /** 61 | * Creates a new instance with the specified id. This is preferred to the 62 | * default constructor when the id is known to prevent unnecessary consumption on 63 | * entropy which can be slow. 64 | * 65 | * @param id the identifier to use 66 | */ 67 | public MapSession(String id) { 68 | this.id = id; 69 | } 70 | 71 | @SuppressWarnings("unchecked") 72 | public T getAttribute(String attributeName) { 73 | return (T) sessionAttrs.get(attributeName); 74 | } 75 | 76 | public Set getAttributeNames() { 77 | return sessionAttrs.keySet(); 78 | } 79 | 80 | public void setAttribute(String attributeName, Object attributeValue) { 81 | if (attributeValue == null) { 82 | removeAttribute(attributeName); 83 | } else { 84 | sessionAttrs.put(attributeName, attributeValue); 85 | } 86 | } 87 | 88 | public void removeAttribute(String attributeName) { 89 | sessionAttrs.remove(attributeName); 90 | } 91 | 92 | public void invalidate() { 93 | invalidated = true; 94 | } 95 | 96 | public long getLastAccessedTime() { 97 | return lastAccessedTime; 98 | } 99 | 100 | public void setLastAccessedTime(long lastAccessedTime) { 101 | this.lastAccessedTime = lastAccessedTime; 102 | } 103 | 104 | @Override 105 | public String getId() { 106 | 107 | return id; 108 | } 109 | 110 | public long getCreationTime() { 111 | return creationTime; 112 | } 113 | 114 | public boolean isInvalidated() { 115 | return invalidated; 116 | } 117 | 118 | @Override 119 | public boolean equals(Object o) { 120 | if (this == o) return true; 121 | if (!(o instanceof MapSession)) return false; 122 | MapSession that = (MapSession) o; 123 | return Objects.equals(id, that.id); 124 | } 125 | 126 | @Override 127 | public int hashCode() { 128 | return Objects.hash(id); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/session/MapSessionRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | /* 19 | * Copyright 2002-2015 the original author or authors. 20 | * 21 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 22 | * use this file except in compliance with the License. You may obtain a copy of 23 | * the License at 24 | * 25 | * http://www.apache.org/licenses/LICENSE-2.0 26 | * 27 | * Unless required by applicable law or agreed to in writing, software 28 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 29 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 30 | * License for the specific language governing permissions and limitations under 31 | * the License. 32 | */ 33 | package love.sola.netsupport.session; 34 | 35 | import com.google.common.cache.CacheBuilder; 36 | import com.google.common.cache.CacheLoader; 37 | import com.google.common.cache.LoadingCache; 38 | 39 | import org.apache.commons.lang3.Validate; 40 | 41 | import java.util.Map; 42 | import java.util.concurrent.TimeUnit; 43 | 44 | import javax.annotation.Nonnull; 45 | 46 | import love.sola.netsupport.config.Settings; 47 | 48 | /** 49 | * @author Sola {@literal } 50 | */ 51 | public class MapSessionRepository { 52 | 53 | private final LoadingCache sessions; 54 | 55 | public MapSessionRepository() { 56 | this(CacheBuilder.newBuilder() 57 | .concurrencyLevel(4) 58 | .maximumSize(65535) 59 | .expireAfterAccess(Settings.I.User_Session_Max_Inactive, TimeUnit.SECONDS) 60 | .build(new CacheLoader() { 61 | @Override 62 | public MapSession load(@Nonnull String key) throws Exception { 63 | return new MapSession(key); 64 | } 65 | } 66 | ) 67 | ); 68 | } 69 | 70 | public MapSessionRepository(LoadingCache sessions) { 71 | Validate.notNull(sessions); 72 | this.sessions = sessions; 73 | } 74 | 75 | public void save(MapSession session) { 76 | sessions.put(session.getId(), session); 77 | } 78 | 79 | public MapSession getSession(String id) { 80 | MapSession saved = sessions.getIfPresent(id); 81 | if (saved == null) { 82 | return null; 83 | } 84 | if (saved.isInvalidated()) { 85 | delete(saved.getId()); 86 | return null; 87 | } 88 | return saved; 89 | } 90 | 91 | public void delete(String id) { 92 | sessions.invalidate(id); 93 | } 94 | 95 | public MapSession createSession() { 96 | MapSession session = new MapSession(); 97 | save(session); 98 | return session; 99 | } 100 | 101 | public Map asMap() { 102 | return sessions.asMap(); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/session/WechatSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.session; 19 | 20 | 21 | import java.util.Collection; 22 | 23 | /** 24 | * @author Sola {@literal } 25 | */ 26 | public class WechatSession { 27 | 28 | private static MapSessionRepository repository; 29 | 30 | static { 31 | repository = new MapSessionRepository(); 32 | } 33 | 34 | public static WxSession get(String id) { 35 | return repository.getSession(id); 36 | } 37 | 38 | public static WxSession create() { 39 | return repository.createSession(); 40 | } 41 | 42 | public static Collection list() { 43 | return repository.asMap().values(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/session/WxSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.session; 19 | 20 | import java.util.Set; 21 | 22 | /** 23 | * @author Sola {@literal } 24 | */ 25 | public interface WxSession { 26 | 27 | String getId(); 28 | 29 | T getAttribute(String name); 30 | 31 | Set getAttributeNames(); 32 | 33 | void setAttribute(String name, Object value); 34 | 35 | void removeAttribute(String name); 36 | 37 | void invalidate(); 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/sql/SQLCore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.sql; 19 | 20 | import com.google.gson.ExclusionStrategy; 21 | import com.google.gson.FieldAttributes; 22 | import com.google.gson.Gson; 23 | import com.google.gson.GsonBuilder; 24 | import com.google.gson.JsonDeserializer; 25 | import com.google.gson.JsonPrimitive; 26 | import com.google.gson.JsonSerializer; 27 | import com.google.gson.TypeAdapter; 28 | import com.google.gson.TypeAdapterFactory; 29 | import com.google.gson.annotations.Expose; 30 | import com.google.gson.reflect.TypeToken; 31 | import com.google.gson.stream.JsonReader; 32 | import com.google.gson.stream.JsonWriter; 33 | import com.mchange.v2.c3p0.ComboPooledDataSource; 34 | 35 | import org.hibernate.Hibernate; 36 | import org.hibernate.Session; 37 | import org.hibernate.SessionFactory; 38 | import org.hibernate.boot.MetadataSources; 39 | import org.hibernate.boot.registry.StandardServiceRegistryBuilder; 40 | import org.hibernate.envers.AuditReader; 41 | import org.hibernate.envers.AuditReaderFactory; 42 | import org.hibernate.proxy.HibernateProxy; 43 | import org.hibernate.service.ServiceRegistry; 44 | 45 | import java.io.IOException; 46 | import java.util.Date; 47 | 48 | import javax.naming.InitialContext; 49 | import javax.naming.NamingException; 50 | import javax.sql.DataSource; 51 | 52 | import love.sola.netsupport.enums.ISP; 53 | import love.sola.netsupport.wechat.Command; 54 | 55 | /** 56 | * @author Sola {@literal } 57 | */ 58 | public class SQLCore { 59 | 60 | public static InitialContext ic; 61 | public static DataSource ds; 62 | public static SessionFactory sf; 63 | public static ServiceRegistry sr; 64 | public static Gson gson = new GsonBuilder() 65 | .addSerializationExclusionStrategy(new ExclusionStrategy() { 66 | @Override 67 | public boolean shouldSkipField(FieldAttributes fieldAttributes) { 68 | final Expose expose = fieldAttributes.getAnnotation(Expose.class); 69 | return expose != null && !expose.serialize(); 70 | } 71 | 72 | @Override 73 | public boolean shouldSkipClass(Class aClass) { 74 | return false; 75 | } 76 | }) 77 | .addDeserializationExclusionStrategy(new ExclusionStrategy() { 78 | @Override 79 | public boolean shouldSkipField(FieldAttributes fieldAttributes) { 80 | final Expose expose = fieldAttributes.getAnnotation(Expose.class); 81 | return expose != null && !expose.deserialize(); 82 | } 83 | 84 | @Override 85 | public boolean shouldSkipClass(Class aClass) { 86 | return false; 87 | } 88 | }) 89 | .registerTypeAdapter(Date.class, (JsonDeserializer) (json, typeOfT, context) -> new Date(json.getAsJsonPrimitive().getAsLong())) 90 | .registerTypeAdapter(Date.class, (JsonSerializer) (src, typeOfSrc, context) -> new JsonPrimitive(src.getTime())) 91 | .registerTypeAdapter(ISP.class, (JsonDeserializer) (json, typeOfT, context) -> ISP.fromId(json.getAsJsonPrimitive().getAsInt())) 92 | .registerTypeAdapter(ISP.class, (JsonSerializer) (src, typeOfSrc, context) -> new JsonPrimitive(src.id)) 93 | .registerTypeAdapter(Command.class, (JsonDeserializer) (json, typeOfT, context) -> Command.fromId(json.getAsJsonPrimitive().getAsInt())) 94 | .registerTypeAdapter(Command.class, (JsonSerializer) (src, typeOfSrc, context) -> new JsonPrimitive(src.id)) 95 | .registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY) 96 | .create(); 97 | 98 | static { 99 | try { 100 | ic = new InitialContext(); 101 | ds = (DataSource) ic.lookup("java:comp/env/jdbc/netsupport"); 102 | ds.setLoginTimeout(3); 103 | 104 | sr = new StandardServiceRegistryBuilder().configure().build(); 105 | sf = new MetadataSources(sr).buildMetadata().buildSessionFactory(); 106 | 107 | TableUser.init(); 108 | TableOperator.init(); 109 | } catch (Exception e) { 110 | e.printStackTrace(); 111 | } 112 | } 113 | 114 | public static void destroy() { 115 | try { 116 | SQLCore.sf.close(); 117 | ((ComboPooledDataSource) SQLCore.ds).close(); 118 | SQLCore.ic.close(); 119 | } catch (NamingException e) { 120 | e.printStackTrace(); 121 | } 122 | } 123 | 124 | public static AuditReader getAuditReader(Session session) { 125 | return AuditReaderFactory.get(session); 126 | } 127 | 128 | public static class HibernateProxyTypeAdapter extends TypeAdapter { 129 | 130 | public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() { 131 | @Override 132 | @SuppressWarnings("unchecked") 133 | public TypeAdapter create(Gson gson, TypeToken type) { 134 | return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter) new HibernateProxyTypeAdapter(gson) : null); 135 | } 136 | }; 137 | private final Gson context; 138 | 139 | private HibernateProxyTypeAdapter(Gson context) { 140 | this.context = context; 141 | } 142 | 143 | @Override 144 | public HibernateProxy read(JsonReader in) throws IOException { 145 | throw new UnsupportedOperationException("Not supported"); 146 | } 147 | 148 | @SuppressWarnings({"rawtypes", "unchecked"}) 149 | @Override 150 | public void write(JsonWriter out, HibernateProxy value) throws IOException { 151 | if (value == null) { 152 | out.nullValue(); 153 | return; 154 | } 155 | // Retrieve the original (not proxy) class 156 | Class baseType = Hibernate.getClass(value); 157 | // Get the TypeAdapter of the original class, to delegate the serialization 158 | TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType)); 159 | // Get a filled instance of the original class 160 | Object unproxiedValue = value.getHibernateLazyInitializer() 161 | .getImplementation(); 162 | // Serialize the value 163 | delegate.write(out, unproxiedValue); 164 | } 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/sql/TableConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.sql; 19 | 20 | import java.sql.Connection; 21 | import java.sql.PreparedStatement; 22 | import java.sql.ResultSet; 23 | import java.sql.SQLException; 24 | import java.sql.Statement; 25 | 26 | import love.sola.netsupport.config.Settings; 27 | 28 | /** 29 | * @author Sola {@literal } 30 | */ 31 | public class TableConfig extends SQLCore { 32 | 33 | public static final String KEY_SYS = "sys"; 34 | 35 | public static Settings getSettings() { 36 | try (Connection conn = ds.getConnection()) { 37 | Statement st = conn.createStatement(); 38 | ResultSet rs = st.executeQuery("SELECT * FROM settings WHERE type='" + KEY_SYS + "'"); 39 | if (rs.next()) { 40 | return gson.fromJson(rs.getString("data"), Settings.class); 41 | } 42 | } catch (SQLException e) { 43 | } 44 | return null; 45 | } 46 | 47 | public static int saveSettings(Settings obj) { 48 | try (Connection conn = ds.getConnection()) { 49 | PreparedStatement ps = conn.prepareStatement("UPDATE settings SET data=? WHERE type=?"); 50 | ps.setString(1, gson.toJson(obj)); 51 | ps.setString(2, KEY_SYS); 52 | return ps.executeUpdate(); 53 | } catch (SQLException e) { 54 | } 55 | return -1; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/sql/TableOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.sql; 19 | 20 | import org.hibernate.Session; 21 | import org.hibernate.criterion.Projections; 22 | import org.hibernate.criterion.Restrictions; 23 | 24 | import love.sola.netsupport.pojo.Operator; 25 | 26 | /** 27 | * @author Sola {@literal } 28 | */ 29 | public class TableOperator extends SQLCore { 30 | 31 | public static boolean has(String wechat) { 32 | try (Session s = SQLCore.sf.openSession()) { 33 | return (long) s.createCriteria(Operator.class) 34 | .add(Restrictions.eq(Operator.PROPERTY_WECHAT, wechat)) 35 | .setProjection(Projections.rowCount()) 36 | .uniqueResult() > 0; 37 | } 38 | } 39 | 40 | 41 | public static Operator get(String wechat) { 42 | try (Session s = SQLCore.sf.openSession()) { 43 | return (Operator) s.createCriteria(Operator.class) 44 | .add(Restrictions.eq(Operator.PROPERTY_WECHAT, wechat)) 45 | .uniqueResult(); 46 | } 47 | } 48 | 49 | public static Operator get(int id) { 50 | try (Session s = SQLCore.sf.openSession()) { 51 | return s.get(Operator.class, id); 52 | } 53 | } 54 | 55 | protected static void init() { 56 | try (Session s = SQLCore.sf.openSession()) { 57 | Operator.USER_SELF = s.get(Operator.class, -1); 58 | Operator.ADMIN = s.get(Operator.class, 0); 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/sql/TableTicket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.sql; 19 | 20 | import love.sola.netsupport.pojo.Operator; 21 | import org.hibernate.Session; 22 | import org.hibernate.criterion.Order; 23 | import org.hibernate.criterion.Projections; 24 | import org.hibernate.criterion.Restrictions; 25 | import org.hibernate.envers.AuditReader; 26 | import org.hibernate.envers.query.AuditEntity; 27 | 28 | import java.util.List; 29 | 30 | import love.sola.netsupport.enums.Status; 31 | import love.sola.netsupport.pojo.Ticket; 32 | import love.sola.netsupport.pojo.User; 33 | import org.hibernate.proxy.HibernateProxy; 34 | 35 | /** 36 | * @author Sola {@literal } 37 | */ 38 | public class TableTicket extends SQLCore { 39 | 40 | public static final String COLUMN_ID = "id"; 41 | public static final String COLUMN_SID = "sid"; 42 | public static final String COLUMN_DESC = "description"; 43 | public static final String COLUMN_SUBMIT_TIME = "submittime"; 44 | public static final String COLUMN_REMARK = "remark"; 45 | public static final String COLUMN_UPDATE_TIME = "updatetime"; 46 | public static final String COLUMN_OPSID = "opsid"; 47 | public static final String COLUMN_STATUS = "status"; 48 | 49 | 50 | public static Ticket latestOpen(User u) { 51 | try (Session s = SQLCore.sf.openSession()) { 52 | return (Ticket) s.createCriteria(Ticket.class) 53 | .addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME)) 54 | .add(Restrictions.eq(Ticket.PROPERTY_USER, u)) 55 | .add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED)) 56 | .setMaxResults(1) 57 | .uniqueResult(); 58 | } 59 | } 60 | 61 | public static Ticket latest(User u) { 62 | try (Session s = SQLCore.sf.openSession()) { 63 | return (Ticket) s.createCriteria(Ticket.class) 64 | .addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME)) 65 | .add(Restrictions.eq(Ticket.PROPERTY_USER, u)) 66 | .setMaxResults(1) 67 | .uniqueResult(); 68 | } 69 | } 70 | 71 | public static boolean hasOpen(User u) { 72 | try (Session s = SQLCore.sf.openSession()) { 73 | return (long) s.createCriteria(Ticket.class) 74 | .add(Restrictions.eq(Ticket.PROPERTY_USER, u)) 75 | .add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED)) 76 | .setProjection(Projections.rowCount()) 77 | .uniqueResult() > 0; 78 | } 79 | } 80 | 81 | @SuppressWarnings("unchecked") 82 | public static List unsolvedByBlock(int b) { 83 | if (b == 0) return unsolved(); 84 | try (Session s = SQLCore.sf.openSession()) { 85 | return s.createCriteria(Ticket.class) 86 | .addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME)) 87 | .add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED)) 88 | .createCriteria(Ticket.PROPERTY_USER) 89 | .add(Restrictions.between(User.PROPERTY_BLOCK, b * 10, (b + 1) * 10 - 1)) 90 | .list(); 91 | } 92 | } 93 | 94 | @SuppressWarnings("unchecked") 95 | public static List unsolved() { 96 | try (Session s = SQLCore.sf.openSession()) { 97 | return s.createCriteria(Ticket.class) 98 | .createAlias(Ticket.PROPERTY_USER, "u") 99 | .addOrder(Order.asc("u." + User.PROPERTY_BLOCK)) 100 | .addOrder(Order.desc(Ticket.PROPERTY_SUBMIT_TIME)) 101 | .add(Restrictions.ne(Ticket.PROPERTY_STATUS, Status.SOLVED)) 102 | .list(); 103 | } 104 | } 105 | 106 | @SuppressWarnings("unchecked") 107 | public static List track(int tid) { 108 | try (Session s = SQLCore.sf.openSession()) { 109 | AuditReader reader = getAuditReader(s); 110 | List resultList = reader.createQuery() 111 | .forRevisionsOfEntity(Ticket.class, false, true) 112 | .addOrder(AuditEntity.revisionNumber().desc()) 113 | .add(AuditEntity.id().eq(tid)) 114 | .getResultList(); 115 | return initializeTickets(resultList); 116 | } 117 | } 118 | 119 | /** 120 | * this is a hacky method to initialize all related entities of ticket 121 | */ 122 | public static List initializeTickets(List resultList) { 123 | for (Object[] result : resultList) { 124 | Ticket value = ((Ticket) result[0]); 125 | HibernateProxy proxiedUser = (HibernateProxy) value.getUser(); 126 | if (proxiedUser != null) { 127 | User unproxiedUser = ((User) proxiedUser.getHibernateLazyInitializer() 128 | .getImplementation()); 129 | value.setUser(unproxiedUser); 130 | } 131 | HibernateProxy proxiedOperator = (HibernateProxy) value.getOperator(); 132 | if (proxiedOperator != null) { 133 | Operator unproxiedOperator = ((Operator) proxiedOperator.getHibernateLazyInitializer() 134 | .getImplementation()); 135 | value.setOperator(unproxiedOperator); 136 | } 137 | } 138 | return resultList; 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/sql/TableUser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.sql; 19 | 20 | import com.google.common.cache.CacheBuilder; 21 | import com.google.common.cache.CacheLoader; 22 | import com.google.common.cache.LoadingCache; 23 | 24 | import org.hibernate.Session; 25 | import org.hibernate.criterion.Restrictions; 26 | 27 | import java.util.concurrent.ExecutionException; 28 | import java.util.concurrent.TimeUnit; 29 | 30 | import love.sola.netsupport.config.Settings; 31 | import love.sola.netsupport.pojo.User; 32 | 33 | /** 34 | * @author Sola {@literal } 35 | */ 36 | @SuppressWarnings("Duplicates") 37 | public class TableUser extends SQLCore { 38 | 39 | public static final String COLUMN_ID = "id"; 40 | public static final String COLUMN_NAME = "name"; 41 | public static final String COLUMN_ISP = "isp"; 42 | public static final String COLUMN_NET_ACCOUNT = "netaccount"; 43 | public static final String COLUMN_WECHAT = "wechat"; 44 | public static final String COLUMN_BLOCK = "block"; 45 | public static final String COLUMN_ROOM = "room"; 46 | public static final String COLUMN_PHONE = "phone"; 47 | 48 | public static User getById(long id) { 49 | try (Session s = sf.openSession()) { 50 | return s.get(User.class, id); 51 | } 52 | } 53 | 54 | public static User getByName(String name) { 55 | try (Session s = sf.openSession()) { 56 | return (User) s.createCriteria(User.class).add(Restrictions.eq(User.PROPERTY_NAME, name)).uniqueResult(); 57 | } 58 | } 59 | 60 | public static User getByWechat(String wechat) { 61 | try { 62 | User u = cache.get(wechat); 63 | return u == NULL_USER ? null : u; 64 | } catch (ExecutionException e) { 65 | e.printStackTrace(); 66 | return null; 67 | } 68 | } 69 | 70 | public static int update(User user) { 71 | try (Session s = sf.openSession()) { 72 | s.beginTransaction(); 73 | s.update(user); 74 | s.getTransaction().commit(); 75 | cache.put(user.getWechatId(), user); 76 | return 1; 77 | } 78 | } 79 | 80 | protected static void init() { 81 | try (Session s = SQLCore.sf.openSession()) { 82 | User.OFFICIAL_CHINA_UNICOM_XH = s.get(User.class, 100104L); 83 | User.OFFICIAL_CHINA_MOBILE_XH = s.get(User.class, 100864L); 84 | User.OFFICIAL_CHINA_MOBILE_FX = s.get(User.class, 100865L); 85 | } 86 | } 87 | 88 | private static LoadingCache cache = CacheBuilder.newBuilder() 89 | .concurrencyLevel(4) 90 | .maximumSize(4096) 91 | .expireAfterAccess(Settings.I.User_Wechat_Cache_Expire_Time, TimeUnit.SECONDS) 92 | .build(new ValueLoader()); 93 | 94 | private static class ValueLoader extends CacheLoader { 95 | @Override 96 | public User load(String key) throws Exception { 97 | User u = TableUser.getByWechat0(key); 98 | return u == null ? NULL_USER : u; 99 | } 100 | } 101 | 102 | private static final User NULL_USER = new User(); 103 | 104 | public static void flushCache() { 105 | cache.invalidateAll(); 106 | } 107 | 108 | private static User getByWechat0(String wechat) { 109 | try (Session s = sf.openSession()) { 110 | return (User) s.createCriteria(User.class).add(Restrictions.eq(User.PROPERTY_WECHAT, wechat)).uniqueResult(); 111 | } 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/util/Checker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.util; 19 | 20 | import love.sola.netsupport.enums.Block; 21 | import love.sola.netsupport.enums.ISP; 22 | 23 | /** 24 | * @author Sola {@literal } 25 | */ 26 | public class Checker { 27 | 28 | public static final String STUDENT_ID_REGEX = "^(2|1)[0-9]{9,12}$"; 29 | public static final String PHONE_NUMBER_REGEX = "^1[3456789][0-9]{9}$"; 30 | 31 | public static boolean hasNull(Object... v) { 32 | for (Object o : v) if (o == null) return true; 33 | return false; 34 | } 35 | 36 | public static long checkStudentId(String studentId) { 37 | if (studentId == null) return -1; 38 | if (studentId.matches(STUDENT_ID_REGEX)) { 39 | try { 40 | return Long.parseLong(studentId); 41 | } catch (NumberFormatException ignored) { 42 | } 43 | } 44 | return -1; 45 | } 46 | 47 | public static long checkPhoneNumber(String phone) { 48 | if (phone == null) return -1; 49 | if (!phone.matches(PHONE_NUMBER_REGEX)) return -1; 50 | try { 51 | return Long.parseLong(phone); 52 | } catch (NumberFormatException ignored) { 53 | } 54 | return -1; 55 | } 56 | 57 | public static ISP checkISP(String isp) { 58 | if (isp == null) return null; 59 | try { 60 | return ISP.fromId(Integer.parseInt(isp)); 61 | } catch (NumberFormatException ignored) { 62 | } 63 | return null; 64 | } 65 | 66 | public static String checkNetAccount(String account, ISP isp) { 67 | if (isp == null) return null; 68 | if (account == null) return null; 69 | if (!account.matches(isp.accountRegex)) return null; 70 | return account; 71 | } 72 | 73 | public static int checkBlock(String block) { 74 | if (block == null) return -1; 75 | try { 76 | int b = Integer.parseInt(block); 77 | if (Block.inverseMap.containsKey(b)) 78 | return b; 79 | else 80 | return -1; 81 | } catch (NumberFormatException ignored) { 82 | } 83 | return -1; 84 | } 85 | 86 | public static int checkRoom(String room, int block) { 87 | if (block == -1) return -1; 88 | if (room == null) return -1; 89 | try { 90 | Integer i = Integer.parseInt(room); 91 | if (Block.checkRoom(block, i)) 92 | return i; 93 | else 94 | return -1; 95 | } catch (NumberFormatException ignored) { 96 | } 97 | return -1; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/util/Crypto.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.util; 19 | 20 | import org.mindrot.jbcrypt.BCrypt; 21 | 22 | /** 23 | * @author Sola {@literal } 24 | */ 25 | public class Crypto { 26 | 27 | public static String hash(String pw) { 28 | return BCrypt.hashpw(pw, BCrypt.gensalt()); 29 | } 30 | 31 | public static boolean check(String plain, String hash) { 32 | return BCrypt.checkpw(plain, hash); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/util/ParseUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.util; 19 | 20 | import java.text.SimpleDateFormat; 21 | 22 | import love.sola.netsupport.enums.Status; 23 | import love.sola.netsupport.pojo.Ticket; 24 | 25 | import static love.sola.netsupport.config.Lang.lang; 26 | 27 | /** 28 | * @author Sola {@literal } 29 | */ 30 | public class ParseUtil { 31 | 32 | public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm EEE"); 33 | 34 | public static String parseTicket(Ticket t) { 35 | StringBuilder sb = new StringBuilder() 36 | .append(lang("Ticket_Info_Id")).append(t.getId()).append("\n") 37 | .append(lang("Ticket_Info_Desc")).append(t.getDescription()).append("\n") 38 | .append(lang("Ticket_Info_Submit_Time")).append(dateFormat.format(t.getSubmitTime())).append("\n"); 39 | if (t.getOperator() != null) 40 | sb.append(lang("Ticket_Info_Operator")).append(t.getOperator().getId()).append("\n"); 41 | if (t.getRemark() != null) 42 | sb.append(lang("Ticket_Info_Remark")).append(t.getRemark()).append("\n"); 43 | if (t.getUpdateTime() != null) 44 | sb.append(lang("Ticket_Info_Update_Time")).append(dateFormat.format(t.getUpdateTime())).append("\n"); 45 | sb.append(lang("Ticket_Info_Status")).append(Status.getLocalized(t.getStatus())); 46 | return sb.toString(); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/util/Redirect.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.util; 19 | 20 | import com.google.common.net.UrlEscapers; 21 | 22 | import java.io.IOException; 23 | 24 | import javax.servlet.http.HttpServletResponse; 25 | 26 | import static love.sola.netsupport.config.Lang.lang; 27 | 28 | /** 29 | * @author Sola {@literal } 30 | */ 31 | public class Redirect { 32 | 33 | private static final String REDIRECT_PAGE = lang("Result_Page"); 34 | 35 | private static final int SUCCESS = 1; 36 | private static final int ERROR = 0; 37 | private static final int WARNING = -1; 38 | private static final int NON_WECHAT = 88; 39 | 40 | public static RedirectBuilder success() { 41 | return new RedirectBuilder(SUCCESS); 42 | } 43 | 44 | public static RedirectBuilder error() { 45 | return new RedirectBuilder(ERROR); 46 | } 47 | 48 | public static class RedirectBuilder { 49 | 50 | private StringBuilder sb; 51 | 52 | RedirectBuilder(int type) { 53 | sb = new StringBuilder(REDIRECT_PAGE).append("?"); 54 | type(type); 55 | } 56 | 57 | private RedirectBuilder type(int type) { 58 | sb.append("type=").append(type).append("&"); 59 | return this; 60 | } 61 | 62 | public RedirectBuilder msg(String msg) { 63 | sb.append("msg=").append(escape(msg)).append("&"); 64 | return this; 65 | } 66 | 67 | public RedirectBuilder title(String title) { 68 | sb.append("title=").append(escape(title)).append("&"); 69 | return this; 70 | } 71 | 72 | public RedirectBuilder noButton() { 73 | sb.append("btn=").append("hide").append("&"); 74 | return this; 75 | } 76 | 77 | public RedirectBuilder button(String text) { 78 | sb.append("btn=").append(escape(text)).append("&"); 79 | return this; 80 | } 81 | 82 | public RedirectBuilder icon(WeUIIcon icon) { 83 | sb.append("icon=").append(icon.toString()).append("&"); 84 | return this; 85 | } 86 | 87 | public RedirectBuilder to(String url) { 88 | sb.append("redirect=").append(escape(url)).append("&"); 89 | return this; 90 | } 91 | 92 | public void go(HttpServletResponse resp) throws IOException { 93 | resp.sendRedirect(sb.toString()); 94 | } 95 | 96 | public String toString() { 97 | return sb.toString(); 98 | } 99 | 100 | private static String escape(String str) { 101 | return UrlEscapers.urlFragmentEscaper().escape(str); 102 | } 103 | 104 | } 105 | 106 | public enum WeUIIcon { 107 | SUCCESS("weui_icon_success"), 108 | SUCCESS_CIRCLE("weui_icon_success_circle"), 109 | SUCCESS_NO_CIRCLE("weui_icon_success_no_circle"), 110 | SUCCESS_SAFE("weui_icon_safe_success"), 111 | INFO("weui_icon_info"), 112 | INFO_CIRCLE("weui_icon_info_circle"), 113 | WAITING("weui_icon_waiting"), 114 | WAITING_CIRCLE("weui_icon_waiting_circle"), 115 | CIRCLE("weui_icon_circle"), 116 | WARN("weui_icon_warn"), 117 | WARN_SAFE("weui_icon_safe_warn"), 118 | DOWNLOAD("weui_icon_download"), 119 | CANCEL("weui_icon_cancel"), 120 | ; 121 | 122 | private String value; 123 | 124 | WeUIIcon(String value) { 125 | this.value = value; 126 | } 127 | 128 | @Override 129 | public String toString() { 130 | return value; 131 | } 132 | 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/Command.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat; 19 | 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | import love.sola.netsupport.wechat.handler.CancelHandler; 24 | import love.sola.netsupport.wechat.handler.ProfileHandler; 25 | import love.sola.netsupport.wechat.handler.QueryHandler; 26 | import love.sola.netsupport.wechat.handler.RegisterHandler; 27 | import love.sola.netsupport.wechat.handler.SubmitHandler; 28 | import love.sola.netsupport.wechat.handler.admin.LoginHandler; 29 | import love.sola.netsupport.wechat.handler.admin.OperatorInfoHandler; 30 | import love.sola.netsupport.wechat.handler.admin.SignHandler; 31 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 32 | 33 | import static love.sola.netsupport.config.Lang.lang; 34 | 35 | /** 36 | * @author Sola {@literal } 37 | */ 38 | public enum Command { 39 | 40 | REGISTER(0, RegisterHandler.class), 41 | QUERY(1, QueryHandler.class), 42 | SUBMIT(2, SubmitHandler.class), 43 | CANCEL(3, CancelHandler.class), 44 | PROFILE(4, ProfileHandler.class), 45 | LOGIN(10, LoginHandler.class), 46 | OPERATOR_INFO(11, OperatorInfoHandler.class), 47 | SIGN(12, SignHandler.class), //FIXME 48 | ; 49 | 50 | private static final Map ID_MAP = new HashMap<>(); 51 | 52 | static { 53 | for (Command type : values()) { 54 | if (type.id >= 0) { 55 | ID_MAP.put(type.id, type); 56 | } 57 | } 58 | } 59 | 60 | public final String regex; 61 | public final Class handler; 62 | public final int id; 63 | 64 | Command(int id, Class handler) { 65 | this.id = id; 66 | this.regex = lang("REGEX_" + name()); 67 | this.handler = handler; 68 | } 69 | 70 | public static Command fromId(int id) { 71 | return ID_MAP.get(id); 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return name(); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/WxMpServlet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat; 19 | 20 | import java.io.IOException; 21 | 22 | import javax.servlet.ServletException; 23 | import javax.servlet.annotation.WebServlet; 24 | import javax.servlet.http.HttpServlet; 25 | import javax.servlet.http.HttpServletRequest; 26 | import javax.servlet.http.HttpServletResponse; 27 | 28 | import love.sola.netsupport.auth.OAuth2; 29 | import love.sola.netsupport.auth.OAuth2Handler; 30 | import love.sola.netsupport.config.Settings; 31 | import love.sola.netsupport.sql.SQLCore; 32 | import love.sola.netsupport.wechat.handler.RegisterHandler; 33 | import love.sola.netsupport.wechat.handler.SubscribeHandler; 34 | import love.sola.netsupport.wechat.matcher.CheckSpamMatcher; 35 | import love.sola.netsupport.wechat.matcher.RegisterMatcher; 36 | import me.chanjar.weixin.common.api.WxConsts; 37 | import me.chanjar.weixin.common.util.StringUtils; 38 | import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; 39 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 40 | import me.chanjar.weixin.mp.api.WxMpMessageRouter; 41 | import me.chanjar.weixin.mp.api.WxMpService; 42 | import me.chanjar.weixin.mp.api.WxMpServiceImpl; 43 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 44 | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 45 | 46 | import static love.sola.netsupport.config.Lang.lang; 47 | 48 | /** 49 | * @author Sola {@literal } 50 | */ 51 | @WebServlet(name = "WxMpServlet", urlPatterns = "/wechat", loadOnStartup = 99) 52 | public class WxMpServlet extends HttpServlet { 53 | 54 | public static WxMpServlet instance; 55 | protected WxMpInMemoryConfigStorage config; 56 | public WxMpService wxMpService; 57 | protected WxMpMessageRouter wxMpMessageRouter; 58 | protected CheckSpamMatcher checkSpamMatcher; 59 | 60 | public WxMpServlet() { 61 | instance = this; 62 | } 63 | 64 | @Override 65 | public void init() throws ServletException { 66 | super.init(); 67 | 68 | config = new WxMpInMemoryConfigStorage(); 69 | config.setAppId(Settings.I.Wechat_AppId); 70 | config.setSecret(Settings.I.Wechat_Secret); 71 | config.setToken(Settings.I.Wechat_Token); 72 | config.setAesKey(Settings.I.Wechat_AesKey); 73 | 74 | wxMpService = new WxMpServiceImpl(); 75 | wxMpService.setWxMpConfigStorage(config); 76 | 77 | checkSpamMatcher = new CheckSpamMatcher(); 78 | wxMpMessageRouter = new WxMpMessageRouter(wxMpService); 79 | wxMpMessageRouter.rule() 80 | .async(false) 81 | .msgType(WxConsts.XML_MSG_EVENT) 82 | .event(WxConsts.EVT_SUBSCRIBE) 83 | .handler(new SubscribeHandler()) 84 | .end(); 85 | wxMpMessageRouter.rule() 86 | .async(false) 87 | .matcher(new CheckSpamMatcher()) 88 | .handler((wxMessage, context, wxMpService1, sessionManager) 89 | -> WxMpXmlOutMessage.TEXT() 90 | .fromUser(wxMessage.getToUserName()) 91 | .toUser(wxMessage.getFromUserName()) 92 | .content(lang("Message_Spam")).build()) 93 | .end(); 94 | wxMpMessageRouter.rule() 95 | .async(false) 96 | .matcher(new RegisterMatcher()) 97 | .handler(new RegisterHandler()) 98 | .end(); 99 | try { 100 | registerCommands(wxMpMessageRouter); 101 | } catch (IllegalAccessException | InstantiationException e) { 102 | throw new ServletException(e); 103 | } 104 | } 105 | 106 | public static void registerCommands(WxMpMessageRouter router) throws IllegalAccessException, InstantiationException { 107 | for (Command c : Command.values()) { 108 | WxMpMessageHandler handler = c.handler.newInstance(); 109 | router.rule().async(false).msgType(WxConsts.XML_MSG_TEXT).rContent(c.regex).handler(handler).end(); 110 | router.rule().async(false).msgType(WxConsts.XML_MSG_EVENT).event(WxConsts.EVT_CLICK).eventKey(c.name()).handler(handler).end(); 111 | if (handler instanceof OAuth2Handler) { 112 | OAuth2.registerOAuth2Handler(c.name(), (OAuth2Handler) handler); 113 | } 114 | } 115 | } 116 | 117 | @Override 118 | protected void doPost(HttpServletRequest request, HttpServletResponse response) 119 | throws ServletException, IOException { 120 | 121 | response.setContentType("text/html;charset=utf-8"); 122 | response.setStatus(HttpServletResponse.SC_OK); 123 | 124 | String signature = request.getParameter("signature"); 125 | String nonce = request.getParameter("nonce"); 126 | String timestamp = request.getParameter("timestamp"); 127 | 128 | if (!wxMpService.checkSignature(timestamp, nonce, signature)) { 129 | // Signature fail 130 | response.getWriter().println(lang("Access_Denied")); 131 | return; 132 | } 133 | 134 | String echostr = request.getParameter("echostr"); 135 | if (StringUtils.isNotBlank(echostr)) { 136 | // validate request 137 | response.getWriter().println(echostr); 138 | return; 139 | } 140 | 141 | String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ? "raw" : request.getParameter("encrypt_type"); 142 | 143 | // if ("raw".equals(encryptType)) { 144 | // WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream()); 145 | // WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage); 146 | // if (outMessage == null) { 147 | // outMessage = WxMpXmlOutMessage.TEXT() 148 | // .fromUser(inMessage.getToUserName()) 149 | // .toUser(inMessage.getFromUserName()) 150 | // .content(lang("Invalid_Operation")) 151 | // .build(); 152 | // } 153 | // response.getWriter().write(outMessage.toXml()); 154 | // return; 155 | // } 156 | 157 | if ("aes".equals(encryptType)) { 158 | String msgSignature = request.getParameter("msg_signature"); 159 | WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), config, timestamp, nonce, msgSignature); 160 | WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage); 161 | if (outMessage == null) { 162 | outMessage = WxMpXmlOutMessage.TEXT() 163 | .fromUser(inMessage.getToUserName()) 164 | .toUser(inMessage.getFromUserName()) 165 | .content(lang("Invalid_Operation")) 166 | .build(); 167 | } 168 | response.getWriter().write(outMessage.toEncryptedXml(config)); 169 | return; 170 | } 171 | 172 | response.getWriter().println(lang("Unknown_Encrypt_Type")); 173 | return; 174 | } 175 | 176 | @Override 177 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 178 | doPost(req, resp); 179 | } 180 | 181 | @Override 182 | public void destroy() { 183 | SQLCore.destroy(); 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/handler/AutoReplyHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.handler; 19 | 20 | import java.util.Map; 21 | 22 | import me.chanjar.weixin.common.exception.WxErrorException; 23 | import me.chanjar.weixin.common.session.WxSessionManager; 24 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 25 | import me.chanjar.weixin.mp.api.WxMpService; 26 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 27 | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 28 | 29 | /** 30 | * @author Sola {@literal } 31 | */ 32 | public class AutoReplyHandler implements WxMpMessageHandler { 33 | 34 | @Override 35 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 36 | //TODO auto reply 37 | return null; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/handler/CancelHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.handler; 19 | 20 | import org.hibernate.Session; 21 | 22 | import java.util.Date; 23 | import java.util.Map; 24 | 25 | import love.sola.netsupport.enums.Status; 26 | import love.sola.netsupport.pojo.Operator; 27 | import love.sola.netsupport.pojo.Ticket; 28 | import love.sola.netsupport.pojo.User; 29 | import love.sola.netsupport.sql.SQLCore; 30 | import love.sola.netsupport.sql.TableTicket; 31 | import love.sola.netsupport.sql.TableUser; 32 | import love.sola.netsupport.util.ParseUtil; 33 | import me.chanjar.weixin.common.exception.WxErrorException; 34 | import me.chanjar.weixin.common.session.WxSessionManager; 35 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 36 | import me.chanjar.weixin.mp.api.WxMpService; 37 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 38 | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 39 | import me.chanjar.weixin.mp.bean.WxMpXmlOutNewsMessage; 40 | import me.chanjar.weixin.mp.bean.outxmlbuilder.NewsBuilder; 41 | 42 | import static love.sola.netsupport.config.Lang.lang; 43 | 44 | /** 45 | * @author Sola {@literal } 46 | */ 47 | public class CancelHandler implements WxMpMessageHandler { 48 | 49 | @Override 50 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 51 | User u = TableUser.getByWechat(wxMessage.getFromUserName()); 52 | Ticket t = TableTicket.latestOpen(u); 53 | if (t == null) { 54 | return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) 55 | .content(lang("No_Open_Ticket_Available")).build(); 56 | } 57 | try (Session s = SQLCore.sf.openSession()) { 58 | t.setOperator(Operator.USER_SELF); 59 | t.setUpdateTime(new Date()); 60 | t.setRemark(lang("User_Cancel_Remark")); 61 | t.setStatus(Status.SOLVED); 62 | s.beginTransaction(); 63 | s.update(t); 64 | s.getTransaction().commit(); 65 | NewsBuilder out = WxMpXmlOutMessage.NEWS().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); 66 | WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item(); 67 | item.setTitle(lang("Cancel_Title")); 68 | item.setDescription(ParseUtil.parseTicket(t)); 69 | out.addArticle(item); 70 | return out.build(); 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) 74 | .content(lang("Cancel_Failed")).build(); 75 | } 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/handler/ProfileHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.handler; 19 | 20 | import java.util.Map; 21 | 22 | import javax.servlet.AsyncContext; 23 | import javax.servlet.http.HttpServletResponse; 24 | 25 | import love.sola.netsupport.auth.OAuth2Handler; 26 | import love.sola.netsupport.enums.Attribute; 27 | import love.sola.netsupport.pojo.User; 28 | import love.sola.netsupport.session.WechatSession; 29 | import love.sola.netsupport.session.WxSession; 30 | import love.sola.netsupport.sql.TableUser; 31 | import love.sola.netsupport.util.Redirect; 32 | import love.sola.netsupport.wechat.Command; 33 | import me.chanjar.weixin.common.exception.WxErrorException; 34 | import me.chanjar.weixin.common.session.WxSessionManager; 35 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 36 | import me.chanjar.weixin.mp.api.WxMpService; 37 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 38 | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 39 | import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder; 40 | 41 | import static love.sola.netsupport.config.Lang.format; 42 | import static love.sola.netsupport.config.Lang.lang; 43 | 44 | /** 45 | * @author Sola {@literal } 46 | */ 47 | public class ProfileHandler implements WxMpMessageHandler, OAuth2Handler { 48 | 49 | @Override 50 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 51 | User u = TableUser.getByWechat(wxMessage.getFromUserName()); 52 | WxSession session = WechatSession.create(); 53 | session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE); 54 | session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); 55 | session.setAttribute(Attribute.USER, u); 56 | TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); 57 | out.content(format("Profile_Modify", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()))); 58 | return out.build(); 59 | } 60 | 61 | @Override 62 | public void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session) { 63 | try { 64 | User u = TableUser.getByWechat(user); 65 | if (u == null) { 66 | session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER); 67 | session.setAttribute(Attribute.WECHAT, user); 68 | Redirect.error().icon(Redirect.WeUIIcon.INFO).noButton() 69 | .title(lang("Need_Register_Title")).msg(lang("Need_Register")) 70 | .to(format("User_Register_Link", session.getId())).go(resp); 71 | return; 72 | } 73 | session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE); 74 | session.setAttribute(Attribute.WECHAT, user); 75 | session.setAttribute(Attribute.USER, u); 76 | resp.sendRedirect(format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone())); 77 | } catch (Exception e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/handler/QueryHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.handler; 19 | 20 | import java.util.Map; 21 | 22 | import love.sola.netsupport.enums.Attribute; 23 | import love.sola.netsupport.pojo.Ticket; 24 | import love.sola.netsupport.pojo.User; 25 | import love.sola.netsupport.session.WechatSession; 26 | import love.sola.netsupport.session.WxSession; 27 | import love.sola.netsupport.sql.TableTicket; 28 | import love.sola.netsupport.sql.TableUser; 29 | import love.sola.netsupport.util.ParseUtil; 30 | import love.sola.netsupport.wechat.Command; 31 | import me.chanjar.weixin.common.exception.WxErrorException; 32 | import me.chanjar.weixin.common.session.WxSessionManager; 33 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 34 | import me.chanjar.weixin.mp.api.WxMpService; 35 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 36 | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 37 | import me.chanjar.weixin.mp.bean.WxMpXmlOutNewsMessage; 38 | import me.chanjar.weixin.mp.bean.outxmlbuilder.NewsBuilder; 39 | 40 | import static love.sola.netsupport.config.Lang.format; 41 | import static love.sola.netsupport.config.Lang.lang; 42 | 43 | /** 44 | * @author Sola {@literal } 45 | */ 46 | public class QueryHandler implements WxMpMessageHandler { 47 | 48 | 49 | @Override 50 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 51 | User u = TableUser.getByWechat(wxMessage.getFromUserName()); 52 | Ticket t = TableTicket.latest(u); 53 | if (t == null) { 54 | return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) 55 | .content(lang("No_Ticket_Available")).build(); 56 | } 57 | WxSession session = WechatSession.create(); 58 | session.setAttribute(Attribute.AUTHORIZED, Command.QUERY); 59 | session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); 60 | session.setAttribute(Attribute.USER, u); 61 | 62 | NewsBuilder out = WxMpXmlOutMessage.NEWS().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); 63 | WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item(); 64 | item.setTitle(lang("Query_Title")); 65 | item.setDescription(ParseUtil.parseTicket(t) + "\n" + lang("More_Details")); 66 | item.setUrl(format("User_Query_Link", session.getId())); 67 | out.addArticle(item); 68 | return out.build(); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/handler/RegisterHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.handler; 19 | 20 | import java.util.Map; 21 | 22 | import love.sola.netsupport.enums.Attribute; 23 | import love.sola.netsupport.pojo.User; 24 | import love.sola.netsupport.session.WechatSession; 25 | import love.sola.netsupport.session.WxSession; 26 | import love.sola.netsupport.sql.TableUser; 27 | import love.sola.netsupport.wechat.Command; 28 | import me.chanjar.weixin.common.exception.WxErrorException; 29 | import me.chanjar.weixin.common.session.WxSessionManager; 30 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 31 | import me.chanjar.weixin.mp.api.WxMpService; 32 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 33 | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 34 | import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder; 35 | 36 | import static love.sola.netsupport.config.Lang.format; 37 | 38 | /** 39 | * @author Sola {@literal } 40 | */ 41 | public class RegisterHandler implements WxMpMessageHandler { 42 | 43 | @Override 44 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService, WxSessionManager sessionManager) 45 | throws WxErrorException { 46 | TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); 47 | String fromUser = wxMessage.getFromUserName(); 48 | User u = TableUser.getByWechat(fromUser); 49 | WxSession session = WechatSession.create(); 50 | if (u != null) { 51 | session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE); 52 | session.setAttribute(Attribute.WECHAT, fromUser); 53 | session.setAttribute(Attribute.USER, u); 54 | out.content(format("Already_Registered", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone()))); 55 | } else { 56 | session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER); 57 | session.setAttribute(Attribute.WECHAT, fromUser); 58 | out.content(format("User_Register", format("User_Register_Link", session.getId()))); 59 | } 60 | return out.build(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/handler/SubmitHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.handler; 19 | 20 | import java.util.Map; 21 | 22 | import love.sola.netsupport.enums.Attribute; 23 | import love.sola.netsupport.pojo.User; 24 | import love.sola.netsupport.session.WechatSession; 25 | import love.sola.netsupport.session.WxSession; 26 | import love.sola.netsupport.sql.TableTicket; 27 | import love.sola.netsupport.sql.TableUser; 28 | import love.sola.netsupport.wechat.Command; 29 | import me.chanjar.weixin.common.exception.WxErrorException; 30 | import me.chanjar.weixin.common.session.WxSessionManager; 31 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 32 | import me.chanjar.weixin.mp.api.WxMpService; 33 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 34 | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 35 | import me.chanjar.weixin.mp.bean.WxMpXmlOutNewsMessage; 36 | import me.chanjar.weixin.mp.bean.outxmlbuilder.NewsBuilder; 37 | 38 | import static love.sola.netsupport.config.Lang.format; 39 | import static love.sola.netsupport.config.Lang.lang; 40 | 41 | /** 42 | * @author Sola {@literal } 43 | */ 44 | public class SubmitHandler implements WxMpMessageHandler { 45 | 46 | @Override 47 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 48 | User u = TableUser.getByWechat(wxMessage.getFromUserName()); 49 | if (TableTicket.hasOpen(u)) { 50 | return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) 51 | .content(lang("Already_Opening_Ticket")).build(); 52 | } 53 | WxSession session = WechatSession.create(); 54 | session.setAttribute(Attribute.AUTHORIZED, Command.SUBMIT); 55 | session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); 56 | session.setAttribute(Attribute.USER, u); 57 | 58 | NewsBuilder out = WxMpXmlOutMessage.NEWS().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); 59 | WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item(); 60 | item.setTitle(lang("Submit_Title")); 61 | item.setDescription(lang("Submit_Desc")); 62 | item.setUrl(format("User_Submit_Link", session.getId(), u.getName(), u.getIsp().id, u.getRoom(), u.getBlock(), u.getPhone())); 63 | out.addArticle(item); 64 | return out.build(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/handler/SubscribeHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.handler; 19 | 20 | import java.util.Map; 21 | 22 | import love.sola.netsupport.enums.Attribute; 23 | import love.sola.netsupport.pojo.Operator; 24 | import love.sola.netsupport.pojo.User; 25 | import love.sola.netsupport.session.WechatSession; 26 | import love.sola.netsupport.session.WxSession; 27 | import love.sola.netsupport.sql.TableOperator; 28 | import love.sola.netsupport.sql.TableUser; 29 | import love.sola.netsupport.wechat.Command; 30 | import me.chanjar.weixin.common.exception.WxErrorException; 31 | import me.chanjar.weixin.common.session.WxSessionManager; 32 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 33 | import me.chanjar.weixin.mp.api.WxMpService; 34 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 35 | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 36 | import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder; 37 | 38 | import static love.sola.netsupport.config.Lang.format; 39 | 40 | /** 41 | * @author Sola {@literal } 42 | */ 43 | public class SubscribeHandler implements WxMpMessageHandler { 44 | 45 | @Override 46 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 47 | TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); 48 | String fromUser = wxMessage.getFromUserName(); 49 | User u = TableUser.getByWechat(fromUser); 50 | WxSession session = WechatSession.create(); 51 | if (u != null) { 52 | session.setAttribute(Attribute.AUTHORIZED, Command.PROFILE); 53 | session.setAttribute(Attribute.WECHAT, fromUser); 54 | session.setAttribute(Attribute.USER, u); 55 | out.content(format("Event_Subscribe", format("Already_Registered", format("User_Profile_Link", session.getId(), u.getName(), u.getIsp().id, u.getNetAccount(), u.getBlock(), u.getRoom(), u.getPhone())))); 56 | 57 | Operator op = TableOperator.get(fromUser); 58 | if (op != null) { 59 | wxMpService.userUpdateGroup(fromUser, 100L); 60 | } 61 | } else { 62 | session.setAttribute(Attribute.AUTHORIZED, Command.REGISTER); 63 | session.setAttribute(Attribute.WECHAT, fromUser); 64 | out.content(format("Event_Subscribe", format("User_Register", format("User_Register_Link", session.getId())))); 65 | } 66 | return out.build(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/handler/admin/LoginHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.handler.admin; 19 | 20 | import java.util.Map; 21 | 22 | import javax.servlet.AsyncContext; 23 | import javax.servlet.http.HttpServletResponse; 24 | 25 | import love.sola.netsupport.auth.OAuth2Handler; 26 | import love.sola.netsupport.enums.Access; 27 | import love.sola.netsupport.enums.Attribute; 28 | import love.sola.netsupport.pojo.Operator; 29 | import love.sola.netsupport.session.WechatSession; 30 | import love.sola.netsupport.session.WxSession; 31 | import love.sola.netsupport.sql.TableOperator; 32 | import love.sola.netsupport.util.Redirect; 33 | import love.sola.netsupport.wechat.Command; 34 | import me.chanjar.weixin.common.exception.WxErrorException; 35 | import me.chanjar.weixin.common.session.WxSessionManager; 36 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 37 | import me.chanjar.weixin.mp.api.WxMpService; 38 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 39 | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 40 | import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder; 41 | 42 | import static love.sola.netsupport.config.Lang.format; 43 | import static love.sola.netsupport.config.Lang.lang; 44 | 45 | /** 46 | * @author Sola {@literal } 47 | */ 48 | public class LoginHandler implements WxMpMessageHandler, OAuth2Handler { 49 | 50 | @Override 51 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 52 | TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); 53 | try { 54 | Operator operator = TableOperator.get(wxMessage.getFromUserName()); 55 | if (operator == null) 56 | out.content(lang("Not_Operator")); 57 | else if (operator.getAccess() >= Access.NO_LOGIN) { 58 | out.content(lang("No_Login")); 59 | } else { 60 | WxSession session = WechatSession.create(); 61 | session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN); 62 | session.setAttribute(Attribute.WECHAT, wxMessage.getFromUserName()); 63 | session.setAttribute(Attribute.OPERATOR, operator); 64 | out.content(format("Home_Page_Msg", format("Operator_Home_Page", session.getId()))); 65 | } 66 | } catch (Exception e) { 67 | e.printStackTrace(); 68 | out.content(lang("Login_Error")); 69 | } 70 | return out.build(); 71 | } 72 | 73 | 74 | @Override 75 | public void onOAuth2(AsyncContext actx, HttpServletResponse resp, String user, WxSession session) { 76 | try { 77 | Operator operator = TableOperator.get(user); 78 | if (operator == null) { 79 | Redirect.error().icon(Redirect.WeUIIcon.WARN_SAFE).noButton() 80 | .title(lang("Not_Operator")).msg(lang("Not_Operator_OAuth2")).go(resp); 81 | return; 82 | } 83 | if (operator.getAccess() >= Access.NO_LOGIN) { 84 | Redirect.error().icon(Redirect.WeUIIcon.WAITING).noButton() 85 | .title(lang("Left_Operator_Title")).msg(lang("Left_Operator")).go(resp); 86 | return; 87 | } 88 | session.setAttribute(Attribute.AUTHORIZED, Command.LOGIN); 89 | session.setAttribute(Attribute.WECHAT, user); 90 | session.setAttribute(Attribute.OPERATOR, operator); 91 | resp.sendRedirect(format("Operator_Home_Page", session.getId())); 92 | } catch (Exception e) { 93 | e.printStackTrace(); 94 | } 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/handler/admin/OperatorInfoHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.handler.admin; 19 | 20 | import java.util.Map; 21 | 22 | import love.sola.netsupport.pojo.Operator; 23 | import love.sola.netsupport.sql.TableOperator; 24 | import me.chanjar.weixin.common.exception.WxErrorException; 25 | import me.chanjar.weixin.common.session.WxSessionManager; 26 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 27 | import me.chanjar.weixin.mp.api.WxMpService; 28 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 29 | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 30 | import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder; 31 | 32 | import static love.sola.netsupport.config.Lang.format; 33 | import static love.sola.netsupport.config.Lang.lang; 34 | 35 | /** 36 | * @author Sola {@literal } 37 | */ 38 | public class OperatorInfoHandler implements WxMpMessageHandler { 39 | 40 | @Override 41 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 42 | TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); 43 | try { 44 | Operator op = TableOperator.get(wxMessage.getFromUserName()); 45 | if (op == null) { 46 | out.content(lang("Not_Operator")); 47 | // } else if (op.getAccess() >= Access.NO_LOGIN) { 48 | // out.content(lang("No_Login")); 49 | } else { 50 | out.content(format("Operator_Info", op.getId(), op.getName(), op.getAccess(), op.getBlock(), op.getWeek())); 51 | } 52 | } catch (Exception e) { 53 | e.printStackTrace(); 54 | out.content(lang("Login_Error")); 55 | } 56 | return out.build(); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/handler/admin/SignHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.handler.admin; 19 | 20 | import java.sql.Connection; 21 | import java.sql.PreparedStatement; 22 | import java.sql.ResultSet; 23 | import java.sql.SQLException; 24 | import java.util.Map; 25 | import java.util.regex.Matcher; 26 | import java.util.regex.Pattern; 27 | 28 | import love.sola.netsupport.sql.SQLCore; 29 | import me.chanjar.weixin.common.exception.WxErrorException; 30 | import me.chanjar.weixin.common.session.WxSessionManager; 31 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 32 | import me.chanjar.weixin.mp.api.WxMpService; 33 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 34 | import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 35 | import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder; 36 | 37 | /** 38 | * @author Sola {@literal } 39 | * @deprecated limited time only 40 | */ 41 | @Deprecated 42 | public class SignHandler implements WxMpMessageHandler { 43 | 44 | public static Pattern pat = Pattern.compile("^(?i)Auth (\\d{4})"); 45 | public static final int INVALID_ID = -1; 46 | public static final int SIGNED_ID = -2; 47 | 48 | @Override 49 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { 50 | String msg = wxMessage.getContent(); 51 | TextBuilder out = WxMpXmlOutMessage.TEXT().toUser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName()); 52 | Matcher mat = pat.matcher(msg); 53 | 54 | root: 55 | if (mat.find()) { 56 | int id = Integer.parseInt(mat.group(1)); 57 | try (Connection conn = SQLCore.ds.getConnection()) { 58 | switch (checkID(conn, id)) { 59 | case INVALID_ID: 60 | out.content("无效ID。"); 61 | break root; 62 | case SIGNED_ID: 63 | out.content("该ID已登记过。"); 64 | break root; 65 | } 66 | if (checkDuplicated(conn, wxMessage.getFromUserName())) { 67 | out.content("你的微信已经登记过。"); 68 | break root; 69 | } 70 | PreparedStatement ps = conn.prepareStatement("UPDATE auth SET wechat=? WHERE id=?"); 71 | ps.setString(1, wxMessage.getFromUserName()); 72 | ps.setInt(2, id); 73 | if (ps.executeUpdate() == 1) { 74 | out.content("登记成功。"); 75 | } else { 76 | out.content("登记失败,请联系管理员。"); 77 | } 78 | } catch (SQLException e) { 79 | e.printStackTrace(); 80 | out.content("系统异常,请联系管理员。"); 81 | } 82 | } else { 83 | out.content("无效ID。"); 84 | } 85 | return out.build(); 86 | } 87 | 88 | private static int checkID(Connection conn, int id) throws SQLException { 89 | PreparedStatement ps = conn.prepareStatement("SELECT wechat FROM auth WHERE id=?"); 90 | ps.setInt(1, id); 91 | ResultSet rs = ps.executeQuery(); 92 | if (rs.next()) { 93 | return rs.getString("wechat") != null ? SIGNED_ID : 0; 94 | } else { 95 | return INVALID_ID; 96 | } 97 | } 98 | 99 | private static boolean checkDuplicated(Connection conn, String wechat) throws SQLException { 100 | PreparedStatement ps = conn.prepareStatement("SELECT wechat FROM auth WHERE wechat=?"); 101 | ps.setString(1, wechat); 102 | ResultSet rs = ps.executeQuery(); 103 | return rs.next(); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/matcher/CheckSpamMatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.matcher; 19 | 20 | import com.google.common.cache.CacheBuilder; 21 | import com.google.common.cache.CacheLoader; 22 | import com.google.common.cache.LoadingCache; 23 | 24 | import java.util.concurrent.TimeUnit; 25 | 26 | import love.sola.netsupport.config.Settings; 27 | import me.chanjar.weixin.mp.api.WxMpMessageMatcher; 28 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 29 | 30 | /** 31 | * @author Sola {@literal } 32 | */ 33 | public class CheckSpamMatcher implements WxMpMessageMatcher { 34 | 35 | private class ValueLoader extends CacheLoader { 36 | @Override 37 | public Long load(String key) throws Exception { 38 | return System.currentTimeMillis() + Settings.I.Check_Spam_Interval; 39 | } 40 | } 41 | 42 | private LoadingCache cache = CacheBuilder.newBuilder() 43 | .concurrencyLevel(4) 44 | .maximumSize(4096) 45 | .expireAfterWrite(Settings.I.Check_Spam_Cache_Expire_Time, TimeUnit.SECONDS) 46 | .build(new ValueLoader()); 47 | 48 | @Override 49 | public boolean match(WxMpXmlMessage wxMessage) { 50 | Long l = cache.getIfPresent(wxMessage.getFromUserName()); 51 | if (l != null && l > System.currentTimeMillis()) { 52 | return true; 53 | } 54 | cache.refresh(wxMessage.getFromUserName()); 55 | return false; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/matcher/CommandMatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.matcher; 19 | 20 | import java.util.Map; 21 | import java.util.concurrent.ConcurrentHashMap; 22 | 23 | import love.sola.netsupport.wechat.Command; 24 | import me.chanjar.weixin.mp.api.WxMpMessageMatcher; 25 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 26 | 27 | /** 28 | * @author Sola {@literal } 29 | */ 30 | public class CommandMatcher implements WxMpMessageMatcher { 31 | 32 | public static Map inCmdUsers = new ConcurrentHashMap<>(); 33 | 34 | Command command; 35 | 36 | public CommandMatcher(Command command) { 37 | this.command = command; 38 | } 39 | 40 | @Override 41 | public boolean match(WxMpXmlMessage message) { 42 | String fromUser = message.getFromUserName(); 43 | if (inCmdUsers.containsKey(fromUser)) { 44 | return command == inCmdUsers.get(fromUser); 45 | } else { 46 | return message.getContent().matches(command.regex); 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/love/sola/netsupport/wechat/matcher/RegisterMatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WechatTicketSystem. 3 | * 4 | * WechatTicketSystem is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * WechatTicketSystem is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with WechatTicketSystem. If not, see . 16 | */ 17 | 18 | package love.sola.netsupport.wechat.matcher; 19 | 20 | import love.sola.netsupport.sql.TableUser; 21 | import me.chanjar.weixin.mp.api.WxMpMessageMatcher; 22 | import me.chanjar.weixin.mp.bean.WxMpXmlMessage; 23 | 24 | /** 25 | * @author Sola {@literal } 26 | */ 27 | public class RegisterMatcher implements WxMpMessageMatcher { 28 | 29 | @Override 30 | public boolean match(WxMpXmlMessage message) { 31 | return TableUser.getByWechat(message.getFromUserName()) == null; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/hibernate.cfg.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | java:comp/env/jdbc/netsupport 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | org.hibernate.dialect.MySQL5InnoDBDialect 27 | 28 | 29 | org.hibernate.cache.internal.NoCacheProvider 30 | 31 | 32 | 33 | true 34 | 35 | 36 | validate 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/main/resources/lang.yml: -------------------------------------------------------------------------------- 1 | #System Exception 2 | Access_Denied: 'Access denied.' 3 | Illegal_Request: | 4 | Access denied. 5 | You are doing an illegal request, and our system has logged your behaviors. 6 | You have to take this seriously, you may be banned from our system if you do this frequently. 7 | Unknown_Encrypt_Type: 'Unknown encrypt-type.' 8 | 9 | #Command Regex 10 | REGEX_QUERY: '^(?i)(Query)|(查询)|(cx)$' 11 | REGEX_REGISTER: '^(?i)(Reg(ister)?)|(注册)|(绑定)|(zc)|(bd)$' 12 | REGEX_SUBMIT: '^(?i)(Submit)|(报修)|(保修)|(bx)$' 13 | REGEX_CANCEL: '^(?i)(Cancel)|(取消)|(撤销)|(qx)|(cx)$' 14 | REGEX_LOGIN: '^(?i)Authme$' 15 | REGEX_PROFILE: '^(?i)(EditProfile)|(修改资料)|(修改信息)|(xgzl)|(xgxx)$' 16 | REGEX_OPERATOR_INFO: '^(?i)(OpInfo)|(网维资料)|(wwzl)$' 17 | REGEX_SIGN: '^(?i)Auth (\d{4})$' 18 | 19 | #Misc 20 | Invalid_Operation: 'Whoops,本报修平台暂未开放聊天功能哦,请点击下方菜单选择你想进行的操作。' 21 | Message_Spam: '你的打字速度太快了,喝一杯82年的Java压压惊吧。' 22 | #Subscribe 23 | Event_Subscribe: "欢迎使用电子科技大学中山学院网络维护科微信自助报修平台。\n\n{0}" 24 | #Register 25 | User_Register: "您尚未进行微信绑定。\n>点击这里进行微信绑定操作<" 26 | Already_Registered: '您已进行过微信绑定。若是需要更改个人信息,请 >点击此处<。' 27 | #Query 28 | Query_Title: '最近一次报修记录:' 29 | More_Details: '>>> 查询更早的报修信息,请点击 <<<' 30 | No_Ticket_Available: '您尚未提交过任何报修。' 31 | #Submit 32 | Already_Opening_Ticket: "您上次提交的报修单仍在处理中. 若需要查询报修单状态,请发送 '查询' 。" 33 | Submit_Title: '在网维工作人员上门解决您的问题之前...' 34 | Submit_Desc: | 35 | 在网维工作人员上门解决您的问题之前,您可以尝试以下方法来更有效地解决您的问题: 36 | - 重新插拔您电脑的网线以及墙上的端口。 37 | - 尝试卸载掉您的wifi共享软件并重启电脑。 38 | - 请您检查一下您的账号是否余额充足。 39 | - 若您的电脑出现明显异常,请尝试使用他人的电脑能否正常登录,网维的工作成员主要负责网络的维护工作,可能无法解决您的个人电脑问题。 40 | 41 | 若以上步骤对您没有帮助,请点此提交报修表单。 42 | #Cancel 43 | No_Open_Ticket_Available: '您当前没有未解决的报修表单。' 44 | Cancel_Title: '报修已取消:' 45 | User_Cancel_Remark: '用户手动取消报修。' 46 | Cancel_Failed: '取消失败。' 47 | #Modify 48 | Profile_Modify: '> 点此修改资料 <' 49 | Need_Register_Title: '尚未进行微信绑定' 50 | Need_Register: '您尚未进行微信绑定,3秒后将自动跳转至微信绑定页面。' 51 | #Login 52 | Home_Page_Msg: 'CLICK HERE' 53 | Not_Operator: '嘟嘟嘟……' 54 | Not_Operator_OAuth2: '看起来你并不是我们网维大家族的一员,但我们随时都欢迎你的加入哦!' 55 | No_Login: 'Permission Denied.' 56 | Left_Operator_Title: '一路上有你' 57 | Left_Operator: '网络维护科的茁壮成长离不开每一位成员的陪伴。一路上有你,感谢你对网络维护科的贡献!' 58 | Internal_Error: '啊哦,登录失败了哦。' 59 | #Operator_Info 60 | Operator_Info: | 61 | 网维成员资料: 62 | 网维ID: {0,number,#} 63 | 姓名: {1} 64 | 岗位: {2,choice,0#'Administrator >ω<'|3#值班组长|6#正式成员|7#实习成员|9#'曾经的一员(TдT)'} 65 | 值班片区: {3,choice,0#'全图 >ω<'|1#岐头片区|2#北门片区|3#东门片区|4#香灰片区|5#凤翔片区|8#朝晖片区} 66 | 值班日: {4,choice,0#'2月30日 >ω<'|1#周一|2#周二|3#周三|4#周四|5#周五|6#周六|7#周日} 67 | 68 | 若以上信息有误,请及时联系@15-沙子森。 69 | #URL 70 | User_Register_Link: 'https://wwbx.davisye.cn/nm/v2/user/reg.html?token={0}' 71 | User_Query_Link: 'https://wwbx.davisye.cn/nm/v2/user/list.html?token={0}' 72 | User_Submit_Link: 'https://wwbx.davisye.cn/nm/v2/user/rrepair.html?token={0}&name={1}&isp={2}&room={3}&block={4}&phone={5,number,#}' 73 | User_Profile_Link: 'https://wwbx.davisye.cn/nm/v2/user/modi.html?token={0}&name={1}&isp={2}&username={3}&block={4}&room={5}&phone={6,number,#}' 74 | Result_Page: 'https://wwbx.davisye.cn/nm/v2/result.html' 75 | Operator_Home_Page: 'https://wwbx.davisye.cn/nm/v2/man/home.html?token={0}' 76 | Operator_Login_Page: 'https://wwbx.davisye.cn/nm/v2/man/login.html?pkey={0}' 77 | 78 | #Localized 79 | #Status 80 | STATUS_UNCHECKED: '待处理' 81 | STATUS_SOLVED: '已解决' 82 | #Ticket 83 | Ticket_Info_Id: '报修单号: ' 84 | Ticket_Info_Desc: '' 85 | Ticket_Info_Submit_Time: '提交时间: ' 86 | Ticket_Info_Operator: '操作员: ' 87 | Ticket_Info_Remark: '维修描述: ' 88 | Ticket_Info_Update_Time: '更新时间: ' 89 | Ticket_Info_Status: '报修单状态: ' 90 | -------------------------------------------------------------------------------- /src/main/resources/menu-op.json: -------------------------------------------------------------------------------- 1 | { 2 | "button": [ 3 | { 4 | "name": "我要", 5 | "sub_button": [ 6 | { 7 | "type": "click", 8 | "name": "提交报修", 9 | "key": "SUBMIT" 10 | }, 11 | { 12 | "type": "click", 13 | "name": "查询报修", 14 | "key": "QUERY" 15 | }, 16 | { 17 | "type": "click", 18 | "name": "撤销报修", 19 | "key": "CANCEL" 20 | }, 21 | { 22 | "type": "click", 23 | "name": "修改资料", 24 | "key": "PROFILE" 25 | } 26 | ] 27 | }, 28 | { 29 | "name": "OP", 30 | "sub_button": [ 31 | { 32 | "type": "click", 33 | "name": "网维资料", 34 | "key": "OPERATOR_INFO" 35 | }, 36 | { 37 | "type": "click", 38 | "name": "后台登录", 39 | "key": "LOGIN" 40 | } 41 | ] 42 | } 43 | ], 44 | "matchrule": { 45 | "group_id": "100" 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/resources/menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "button": [ 3 | { 4 | "name": "我要", 5 | "sub_button": [ 6 | { 7 | "type": "click", 8 | "name": "提交报修", 9 | "key": "SUBMIT" 10 | }, 11 | { 12 | "type": "click", 13 | "name": "查询报修", 14 | "key": "QUERY" 15 | }, 16 | { 17 | "type": "click", 18 | "name": "撤销报修", 19 | "key": "CANCEL" 20 | }, 21 | { 22 | "type": "click", 23 | "name": "修改资料", 24 | "key": "PROFILE" 25 | } 26 | ] 27 | }, 28 | { 29 | "name": "关于网维", 30 | "sub_button": [ 31 | { 32 | "type": "view", 33 | "name": "关于报修系统", 34 | "url": "https://wwbx.davisye.cn/nm/v2/" 35 | }, 36 | { 37 | "type": "view", 38 | "name": "联系我们", 39 | "url": "https://wwbx.davisye.cn/nm/v2/404.html" 40 | }, 41 | { 42 | "type": "view", 43 | "name": "关于网维", 44 | "url": "https://wwbx.davisye.cn/nm/v2/404.html" 45 | } 46 | ] 47 | } 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /src/main/webapp/META-INF/context.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | WEB-INF/web.xml 21 | 22 | 23 | 26 | 32 | 34 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | Network Support Application 9 | 10 | If you have any problem, please contact loli@sola.love . 11 | 12 | 13 | 14 | index 15 | 16 | 17 | /index 18 | 19 | 20 | 21 | 10 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/webapp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZSCNetSupportDept/WechatTicketSystem/2cf480ee854653665a3003a6ddb8708ae5f10c83/src/main/webapp/favicon.ico -------------------------------------------------------------------------------- /src/test/java/love/sola/netsupport/api/ReflectionTest.java: -------------------------------------------------------------------------------- 1 | package love.sola.netsupport.api; 2 | 3 | import org.junit.Test; 4 | import org.reflections.Reflections; 5 | 6 | import java.util.Set; 7 | 8 | /** 9 | * @author Sola {@literal } 10 | */ 11 | public class ReflectionTest { 12 | 13 | @Test 14 | public void test() { 15 | Reflections reflections = new Reflections(getClass().getPackage().getName()); 16 | Set> set = reflections.getSubTypesOf(API.class); 17 | assert set.size() == 15; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/love/sola/netsupport/config/ReflectionTest.java: -------------------------------------------------------------------------------- 1 | package love.sola.netsupport.config; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * @author Sola {@literal } 7 | */ 8 | public class ReflectionTest { 9 | 10 | @Test 11 | public void testLang() { 12 | assert Lang.messages != null; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/love/sola/netsupport/enums/ReflectionTest.java: -------------------------------------------------------------------------------- 1 | package love.sola.netsupport.enums; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * @author Sola {@literal } 7 | */ 8 | public class ReflectionTest { 9 | 10 | @Test 11 | public void testBlock() { 12 | assert Block.inverseMap != null; 13 | } 14 | 15 | @Test 16 | public void testAccess() { 17 | assert Access.inverseMap != null; 18 | } 19 | 20 | @Test 21 | public void testStatus() { 22 | assert Status.inverseMap != null; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/love/sola/netsupport/util/GsonTest.java: -------------------------------------------------------------------------------- 1 | package love.sola.netsupport.util; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import com.google.gson.JsonDeserializer; 6 | import com.google.gson.JsonPrimitive; 7 | import com.google.gson.JsonSerializer; 8 | 9 | import org.junit.Test; 10 | 11 | import java.util.Date; 12 | 13 | import love.sola.netsupport.enums.ISP; 14 | 15 | /** 16 | * @author Sola {@literal } 17 | */ 18 | public class GsonTest { 19 | 20 | @Test 21 | public void testJsonDate() { 22 | Gson gson = new GsonBuilder() 23 | .registerTypeAdapter(Date.class, (JsonDeserializer) (json, typeOfT, context) -> new Date(json.getAsJsonPrimitive().getAsLong())) 24 | .registerTypeAdapter(Date.class, (JsonSerializer) (src, typeOfSrc, context) -> new JsonPrimitive(src.getTime())) 25 | .registerTypeAdapter(ISP.class, (JsonDeserializer) (json, typeOfT, context) -> ISP.fromId(json.getAsJsonPrimitive().getAsInt())) 26 | .registerTypeAdapter(ISP.class, (JsonSerializer) (src, typeOfSrc, context) -> new JsonPrimitive(src.id)) 27 | .create(); 28 | Date date = new Date(); 29 | assert gson.fromJson(gson.toJson(date), Date.class).compareTo(date) == 0; 30 | assert gson.fromJson(gson.toJson(ISP.TELECOM), ISP.class) == ISP.TELECOM; 31 | assert gson.toJson(ISP.TELECOM).equals("1"); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/love/sola/netsupport/util/URLEncodeTest.java: -------------------------------------------------------------------------------- 1 | package love.sola.netsupport.util; 2 | 3 | import com.google.common.net.UrlEscapers; 4 | 5 | import org.junit.Test; 6 | 7 | import java.io.UnsupportedEncodingException; 8 | 9 | import static org.hamcrest.CoreMatchers.equalTo; 10 | import static org.junit.Assert.assertThat; 11 | 12 | /** 13 | * @author Sola {@literal } 14 | */ 15 | public class URLEncodeTest { 16 | 17 | @Test 18 | public void testEncode() throws UnsupportedEncodingException { 19 | assertThat( 20 | UrlEscapers.urlFragmentEscaper().escape("Test Title"), 21 | equalTo("Test%20Title") 22 | ); 23 | assertThat( 24 | Redirect.success() 25 | .title("Test Title") 26 | .msg("Test Message") 27 | .toString(), 28 | equalTo("https://wwbx.davisye.cn/nm/v2/result.html?type=1&title=Test%20Title&msg=Test%20Message&") 29 | ); 30 | } 31 | 32 | } 33 | --------------------------------------------------------------------------------