mirror of
				https://github.com/ZSCNetSupportDept/WechatTicketSystem.git
				synced 2025-11-01 02:46:19 +08:00 
			
		
		
		
	Using wechat web brower to register.
This commit is contained in:
		| @@ -1,7 +1,5 @@ | ||||
| package love.sola.netsupport.wechat; | ||||
|  | ||||
| import lombok.Getter; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| @@ -13,7 +11,7 @@ import java.util.Map; | ||||
|  */ | ||||
| public enum Command { | ||||
|  | ||||
| 	REGISTER(0, "Register", "(?i)^Register$"), | ||||
| 	REGISTER(0, "Register", ".*"), | ||||
| 	; | ||||
|  | ||||
| 	private static final Map<Integer, Command> ID_MAP = new HashMap<>(); | ||||
| @@ -26,12 +24,9 @@ public enum Command { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	@Getter | ||||
| 	private final String name; | ||||
| 	@Getter | ||||
| 	private final String regex; | ||||
| 	@Getter | ||||
| 	private final int id; | ||||
| 	public final String name; | ||||
| 	public final String regex; | ||||
| 	public final int id; | ||||
|  | ||||
| 	Command(int id, String name, String regex) { | ||||
| 		this.name = name; | ||||
|   | ||||
| @@ -3,12 +3,11 @@ package love.sola.netsupport.wechat; | ||||
| import love.sola.netsupport.config.Settings; | ||||
| import love.sola.netsupport.wechat.handler.RegisterHandler; | ||||
| import love.sola.netsupport.wechat.intercepter.CheckSpamInterceptor; | ||||
| import love.sola.netsupport.wechat.matcher.CommandMatcher; | ||||
| import love.sola.netsupport.wechat.matcher.RegisterMatcher; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import me.chanjar.weixin.common.session.WxSessionManager; | ||||
| import me.chanjar.weixin.common.util.StringUtils; | ||||
| import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; | ||||
| import me.chanjar.weixin.mp.api.WxMpMessageRouter; | ||||
| import me.chanjar.weixin.mp.api.WxMpService; | ||||
| import me.chanjar.weixin.mp.api.WxMpServiceImpl; | ||||
| import me.chanjar.weixin.mp.api.*; | ||||
| import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | ||||
| import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | ||||
|  | ||||
| @@ -18,6 +17,9 @@ import javax.servlet.http.HttpServlet; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import java.io.IOException; | ||||
| import java.util.Map; | ||||
|  | ||||
| import static love.sola.netsupport.config.Lang.lang; | ||||
|  | ||||
| /** | ||||
|  * *********************************************** | ||||
| @@ -25,7 +27,7 @@ import java.io.IOException; | ||||
|  * Don't modify this source without my agreement | ||||
|  * *********************************************** | ||||
|  */ | ||||
| @WebServlet(name = "WxMpServlet", urlPatterns = "/wechattest", loadOnStartup = 2) | ||||
| @WebServlet(name = "WxMpServlet", urlPatterns = "/wechattest", loadOnStartup = 99) | ||||
| public class WxMpServlet extends HttpServlet { | ||||
|  | ||||
| 	public static WxMpServlet instance; | ||||
| @@ -56,10 +58,24 @@ public class WxMpServlet extends HttpServlet { | ||||
| 		wxMpMessageRouter.rule() | ||||
| 				.async(false) | ||||
| 				.msgType("text") | ||||
| 				.matcher(new CommandMatcher(Command.REGISTER)) | ||||
| 				.matcher(new RegisterMatcher()) | ||||
| 				.handler(new RegisterHandler()) | ||||
| 				.interceptor(checkSpamInterceptor) | ||||
| 				.end(); | ||||
| 		wxMpMessageRouter.rule() | ||||
| 				.async(false) | ||||
| 				.msgType("event") | ||||
| 				.event("subscribe") | ||||
| 				.handler(new WxMpMessageHandler() { | ||||
| 					@Override | ||||
| 					public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException { | ||||
| 						return WxMpXmlOutMessage.TEXT() | ||||
| 								.fromUser(wxMessage.getToUserName()) | ||||
| 								.toUser(wxMessage.getFromUserName()) | ||||
| 								.content(lang("Event_Subscribe")).build(); | ||||
| 					} | ||||
| 				}) | ||||
| 				.end(); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| @@ -75,7 +91,7 @@ public class WxMpServlet extends HttpServlet { | ||||
|  | ||||
| 		if (!wxMpService.checkSignature(timestamp, nonce, signature)) { | ||||
| 			// Signature fail | ||||
| 			response.getWriter().println("Access Denied"); | ||||
| 			response.getWriter().println(lang("Access_Denied")); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| @@ -95,7 +111,7 @@ public class WxMpServlet extends HttpServlet { | ||||
| 				outMessage = WxMpXmlOutMessage.TEXT() | ||||
| 						.fromUser(inMessage.getToUserName()) | ||||
| 						.toUser(inMessage.getFromUserName()) | ||||
| 						.content("Invalid Operation.") | ||||
| 						.content(lang("Invalid_Operation")) | ||||
| 						.build(); | ||||
| 			} | ||||
| 			response.getWriter().write(outMessage.toXml()); | ||||
| @@ -110,14 +126,14 @@ public class WxMpServlet extends HttpServlet { | ||||
| 				outMessage = WxMpXmlOutMessage.TEXT() | ||||
| 						.fromUser(inMessage.getToUserName()) | ||||
| 						.toUser(inMessage.getFromUserName()) | ||||
| 						.content("Invalid Operation.") | ||||
| 						.content(lang("Invalid_Operation")) | ||||
| 						.build(); | ||||
| 			} | ||||
| 			response.getWriter().write(outMessage.toEncryptedXml(config)); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		response.getWriter().println("Unknown encrypt-type"); | ||||
| 		response.getWriter().println(lang("Unknown_Encrypt_Type")); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -1,10 +1,7 @@ | ||||
| package love.sola.netsupport.wechat.handler; | ||||
|  | ||||
| import love.sola.netsupport.enums.ISPType; | ||||
| import love.sola.netsupport.pojo.User; | ||||
| import love.sola.netsupport.sql.TableUser; | ||||
| import love.sola.netsupport.api.Authorize; | ||||
| import love.sola.netsupport.wechat.Command; | ||||
| import love.sola.netsupport.wechat.matcher.CommandMatcher; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import me.chanjar.weixin.common.session.WxSessionManager; | ||||
| import me.chanjar.weixin.mp.api.WxMpMessageHandler; | ||||
| @@ -13,9 +10,10 @@ import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | ||||
| import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | ||||
| import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| import static love.sola.netsupport.config.Lang.format; | ||||
|  | ||||
| /** | ||||
|  * *********************************************** | ||||
|  * Created by Sola on 2015/11/4. | ||||
| @@ -24,123 +22,14 @@ import java.util.Map; | ||||
|  */ | ||||
| public class RegisterHandler implements WxMpMessageHandler { | ||||
|  | ||||
| 	public static final String STUDENT_ID_REGEX = "^(2010|2012|2013|2014|2015)[0-9]{9}"; | ||||
|  | ||||
| 	Map<String, User> confirmed = new HashMap<>(); | ||||
| 	Map<String, RegisterStep> steps = new HashMap<>(); | ||||
|  | ||||
| 	@Override | ||||
|  | ||||
| 	public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) | ||||
| 			throws WxErrorException { | ||||
| 		TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); | ||||
| 		handle(wxMessage.getContent(), wxMessage.getFromUserName(), out); | ||||
| 		out.content(format("User_Register_Link", wxMessage.getFromUserName())); | ||||
| 		Authorize.fetchedTime.put(wxMessage.getFromUserName(), System.currentTimeMillis()); | ||||
| 		Authorize.fetchedCommand.put(wxMessage.getFromUserName(), Command.REGISTER); | ||||
| 		return out.build(); | ||||
| 	} | ||||
|  | ||||
| 	private void handle(String in, String userName, TextBuilder out) { | ||||
| 		if (in.equalsIgnoreCase("q")) { | ||||
| 			CommandMatcher.inCmdUsers.remove(userName); | ||||
| 			confirmed.remove(userName); | ||||
| 			steps.remove(userName); | ||||
| 			out.content("Operation canceled."); | ||||
| 			return; | ||||
| 		} | ||||
| 		if (!steps.containsKey(userName)) { | ||||
| 			out.content("Welcome, please type your student identification number."); | ||||
| 			CommandMatcher.inCmdUsers.put(userName, Command.REGISTER); | ||||
| 			steps.put(userName, RegisterStep.STUDENT_ID); | ||||
| 			return; | ||||
| 		} | ||||
| 		RegisterStep step = steps.get(userName); | ||||
| 		if (step == RegisterStep.STUDENT_ID) { | ||||
| 			Long sid = checkStudentId(in); | ||||
| 			User user; | ||||
| 			if (sid == null || (user = TableUser.getUserById(sid)) == null) { | ||||
| 				out.content("Invalid student identification number. Type 'q' to cancel this operation."); | ||||
| 				return; | ||||
| 			} | ||||
| 			out.content("Please type your real name to validate."); | ||||
| 			confirmed.put(userName, user); | ||||
| 			steps.put(userName, RegisterStep.NAME); | ||||
| 			return; | ||||
| 		} | ||||
| 		User user = confirmed.get(userName); | ||||
| 		if (step == RegisterStep.NAME) { | ||||
| 			if (in.trim().equals(user.getName())) { | ||||
| 				out.content("Confirmed success.\n" + | ||||
| 						"Please enter your ISP.\n" + | ||||
| 						"1-Telecom 2-Unicom 3-ChinaMobile"); | ||||
| 				steps.put(userName, RegisterStep.ISP); | ||||
| 			} else { | ||||
| 				out.content("Validate failed.\n" + | ||||
| 						"If you have any issue, please contact administrator.\n" + | ||||
| 						"Type 'q' to cancel this operation."); | ||||
| 			} | ||||
| 			return; | ||||
| 		} | ||||
| 		if (step == RegisterStep.ISP) { | ||||
| 			ISPType type = checkISP(in); | ||||
| 			if (type == null) { | ||||
| 				out.content("Invalid ISP. Please retype your ISP."); | ||||
| 			} else { | ||||
| 				user.setIsp(type); | ||||
| 				out.content("Success.\n" + | ||||
| 						"Please enter your net account."); | ||||
| 				steps.put(userName, RegisterStep.NET_ACCOUNT); | ||||
| 			} | ||||
| 			return; | ||||
| 		} | ||||
| 		if (step == RegisterStep.NET_ACCOUNT) { | ||||
| 			String account = checkNetAccount(in); | ||||
| 			if (account == null) { | ||||
| 				out.content("Invalid account. Please retype your net account."); | ||||
| 			} else { | ||||
| 				user.setNetAccount(account); | ||||
| 				steps.put(userName, RegisterStep.COMPLETE); | ||||
| 			} | ||||
| 		} | ||||
| 		if (step == RegisterStep.COMPLETE) { | ||||
| 			user.setWechatId(userName); | ||||
| 			TableUser.updateUser(user); | ||||
| 			CommandMatcher.inCmdUsers.remove(userName); | ||||
| 			confirmed.remove(userName); | ||||
| 			steps.remove(userName); | ||||
| 			out.content("Congratulations!\n" + | ||||
| 					"You has successful registered!\n" + | ||||
| 					"Please enjoy our service."); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private Long checkStudentId(String studentId) { | ||||
| 		if (studentId.matches(STUDENT_ID_REGEX)) { | ||||
| 			try { | ||||
| 				return Long.parseLong(studentId); | ||||
| 			} catch (NumberFormatException ignored) { | ||||
| 			} | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
| 	private ISPType checkISP(String isp) { | ||||
| 		try { | ||||
| 			return ISPType.fromId(Integer.parseInt(isp)); | ||||
| 		} catch (NumberFormatException ignored) { | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
| 	private String checkNetAccount(String account) { | ||||
| 		return account; | ||||
| 	} | ||||
|  | ||||
| 	enum RegisterStep { | ||||
| 		STUDENT_ID, | ||||
| 		NAME, | ||||
| 		ISP, | ||||
| 		NET_ACCOUNT, | ||||
| 		COMPLETE, | ||||
| 		; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,146 @@ | ||||
| package love.sola.netsupport.wechat.handler; | ||||
|  | ||||
| import love.sola.netsupport.enums.ISP; | ||||
| import love.sola.netsupport.pojo.User; | ||||
| import love.sola.netsupport.sql.TableUser; | ||||
| import love.sola.netsupport.wechat.Command; | ||||
| import love.sola.netsupport.wechat.matcher.CommandMatcher; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import me.chanjar.weixin.common.session.WxSessionManager; | ||||
| import me.chanjar.weixin.mp.api.WxMpMessageHandler; | ||||
| import me.chanjar.weixin.mp.api.WxMpService; | ||||
| import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | ||||
| import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | ||||
| import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * *********************************************** | ||||
|  * Created by Sola on 2015/11/4. | ||||
|  * Don't modify this source without my agreement | ||||
|  * *********************************************** | ||||
|  */ | ||||
| public class __INVALID__RegisterHandler implements WxMpMessageHandler { | ||||
|  | ||||
| 	public static final String STUDENT_ID_REGEX = "^(2010|2012|2013|2014|2015)[0-9]{9}"; | ||||
|  | ||||
| 	Map<String, User> confirmed = new HashMap<>(); | ||||
| 	Map<String, RegisterStep> steps = new HashMap<>(); | ||||
|  | ||||
| 	@Override | ||||
|  | ||||
| 	public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) | ||||
| 			throws WxErrorException { | ||||
| 		TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()); | ||||
| 		handle(wxMessage.getContent(), wxMessage.getFromUserName(), out); | ||||
| 		return out.build(); | ||||
| 	} | ||||
|  | ||||
| 	private void handle(String in, String userName, TextBuilder out) { | ||||
| 		if (in.equalsIgnoreCase("q")) { | ||||
| 			CommandMatcher.inCmdUsers.remove(userName); | ||||
| 			confirmed.remove(userName); | ||||
| 			steps.remove(userName); | ||||
| 			out.content("Operation canceled."); | ||||
| 			return; | ||||
| 		} | ||||
| 		if (!steps.containsKey(userName)) { | ||||
| 			out.content("Welcome, please type your student identification number."); | ||||
| 			CommandMatcher.inCmdUsers.put(userName, Command.REGISTER); | ||||
| 			steps.put(userName, RegisterStep.STUDENT_ID); | ||||
| 			return; | ||||
| 		} | ||||
| 		RegisterStep step = steps.get(userName); | ||||
| 		if (step == RegisterStep.STUDENT_ID) { | ||||
| 			Long sid = checkStudentId(in); | ||||
| 			User user; | ||||
| 			if (sid == null || (user = TableUser.getUserById(sid)) == null) { | ||||
| 				out.content("Invalid student identification number. Type 'q' to cancel this operation."); | ||||
| 				return; | ||||
| 			} | ||||
| 			out.content("Please type your real name to validate."); | ||||
| 			confirmed.put(userName, user); | ||||
| 			steps.put(userName, RegisterStep.NAME); | ||||
| 			return; | ||||
| 		} | ||||
| 		User user = confirmed.get(userName); | ||||
| 		if (step == RegisterStep.NAME) { | ||||
| 			if (in.trim().equals(user.getName())) { | ||||
| 				out.content("Confirmed success.\n" + | ||||
| 						"Please enter your ISP.\n" + | ||||
| 						"1-Telecom 2-Unicom 3-ChinaMobile"); | ||||
| 				steps.put(userName, RegisterStep.ISP); | ||||
| 			} else { | ||||
| 				out.content("Validate failed.\n" + | ||||
| 						"If you have any issue, please contact administrator.\n" + | ||||
| 						"Type 'q' to cancel this operation."); | ||||
| 			} | ||||
| 			return; | ||||
| 		} | ||||
| 		if (step == RegisterStep.ISP) { | ||||
| 			ISP type = checkISP(in); | ||||
| 			if (type == null) { | ||||
| 				out.content("Invalid ISP. Please retype your ISP."); | ||||
| 			} else { | ||||
| 				user.setIsp(type); | ||||
| 				out.content("Success.\n" + | ||||
| 						"Please enter your net account."); | ||||
| 				steps.put(userName, RegisterStep.NET_ACCOUNT); | ||||
| 			} | ||||
| 			return; | ||||
| 		} | ||||
| 		if (step == RegisterStep.NET_ACCOUNT) { | ||||
| 			String account = checkNetAccount(in); | ||||
| 			if (account == null) { | ||||
| 				out.content("Invalid account. Please retype your net account."); | ||||
| 			} else { | ||||
| 				user.setNetAccount(account); | ||||
| 				steps.put(userName, step = RegisterStep.COMPLETE); | ||||
| 			} | ||||
| 		} | ||||
| 		if (step == RegisterStep.COMPLETE) { | ||||
| 			user.setWechatId(userName); | ||||
| 			TableUser.updateUser(user); | ||||
| 			CommandMatcher.inCmdUsers.remove(userName); | ||||
| 			confirmed.remove(userName); | ||||
| 			steps.remove(userName); | ||||
| 			out.content("Congratulations!\n" + | ||||
| 					"You has successful registered!\n" + | ||||
| 					"Please enjoy our service."); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private Long checkStudentId(String studentId) { | ||||
| 		if (studentId.matches(STUDENT_ID_REGEX)) { | ||||
| 			try { | ||||
| 				return Long.parseLong(studentId); | ||||
| 			} catch (NumberFormatException ignored) { | ||||
| 			} | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
| 	private ISP checkISP(String isp) { | ||||
| 		try { | ||||
| 			return ISP.fromId(Integer.parseInt(isp)); | ||||
| 		} catch (NumberFormatException ignored) { | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
| 	private String checkNetAccount(String account) { | ||||
| 		return account; | ||||
| 	} | ||||
|  | ||||
| 	enum RegisterStep { | ||||
| 		STUDENT_ID, | ||||
| 		NAME, | ||||
| 		ISP, | ||||
| 		NET_ACCOUNT, | ||||
| 		COMPLETE, | ||||
| 		; | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -29,7 +29,7 @@ public class CommandMatcher implements WxMpMessageMatcher { | ||||
| 		if (inCmdUsers.containsKey(fromUser)) { | ||||
| 			return command == inCmdUsers.get(fromUser); | ||||
| 		} else { | ||||
| 			return message.getContent().matches(command.getRegex()); | ||||
| 			return message.getContent().matches(command.regex); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,23 @@ | ||||
| package love.sola.netsupport.wechat.matcher; | ||||
|  | ||||
| import love.sola.netsupport.pojo.User; | ||||
| import love.sola.netsupport.sql.TableUser; | ||||
| import me.chanjar.weixin.mp.api.WxMpMessageMatcher; | ||||
| import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | ||||
|  | ||||
| /** | ||||
|  * *********************************************** | ||||
|  * Created by Sola on 2015/11/26. | ||||
|  * Don't modify this source without my agreement | ||||
|  * *********************************************** | ||||
|  */ | ||||
| public class RegisterMatcher implements WxMpMessageMatcher { | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean match(WxMpXmlMessage message) { | ||||
| 		String fromUser = message.getFromUserName(); | ||||
| 		User u = TableUser.getUserByWechat(fromUser); | ||||
| 		return u == null; | ||||
| 	} | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Sola
					Sola