forked from integrated_whb/integrated_whb
feat(login): 添加短信验证码登录功能
- 在Shiro配置中添加sendSmsCode和checkByCode接口的匿名访问权限 - 在LoginController中新增VerificationCodeService依赖注入 - 实现sendSmsCode接口用于发送手机验证码,支持手机号格式验证 - 实现checkByCode接口用于验证码登录,包含自动注册新用户逻辑 - 创建VerificationCodeService接口和VerificationCodeServiceImpl实现类 - 实现基于内存存储的验证码管理,包含6位数字验证码生成功能 - 添加验证码过期时间控制,默认5分钟过期 - 集成ZTHY短信平台发送验证码功能 - 实现通用验证码888888用于测试环境验证 - 完善验证码验证成功后的用户登录和会话创建流程 - 添加验证码相关的操作日志记录功能演示用
parent
ff279a18a9
commit
c9050f45c4
|
|
@ -63,6 +63,8 @@ public class ShiroConfiguration {
|
||||||
filterChainMap.put("/admin/checkPractitioner", "anon");
|
filterChainMap.put("/admin/checkPractitioner", "anon");
|
||||||
filterChainMap.put("/admin/islogin", "anon");
|
filterChainMap.put("/admin/islogin", "anon");
|
||||||
filterChainMap.put("/admin/register", "anon");
|
filterChainMap.put("/admin/register", "anon");
|
||||||
|
filterChainMap.put("/admin/sendSmsCode", "anon");
|
||||||
|
filterChainMap.put("/admin/checkByCode", "anon");
|
||||||
filterChainMap.put("/admin/adminCheck", "anon");
|
filterChainMap.put("/admin/adminCheck", "anon");
|
||||||
filterChainMap.put("/App**/**", "anon");
|
filterChainMap.put("/App**/**", "anon");
|
||||||
filterChainMap.put("/app/**/**", "anon");
|
filterChainMap.put("/app/**/**", "anon");
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,10 @@ import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.authc.*;
|
import org.apache.shiro.authc.*;
|
||||||
import org.apache.shiro.crypto.hash.SimpleHash;
|
import org.apache.shiro.crypto.hash.SimpleHash;
|
||||||
import org.apache.shiro.session.Session;
|
import org.apache.shiro.session.Session;
|
||||||
|
import org.apache.shiro.subject.PrincipalCollection;
|
||||||
|
import org.apache.shiro.subject.SimplePrincipalCollection;
|
||||||
import org.apache.shiro.subject.Subject;
|
import org.apache.shiro.subject.Subject;
|
||||||
|
import org.apache.shiro.subject.support.DefaultSubjectContext;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
@ -46,6 +49,235 @@ public class LoginController extends BaseController {
|
||||||
private OffDutyService offdutyService;
|
private OffDutyService offdutyService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SupervisionDepartmentService supervisionDepartmentService;
|
private SupervisionDepartmentService supervisionDepartmentService;
|
||||||
|
@Autowired
|
||||||
|
private VerificationCodeService verificationCodeService;
|
||||||
|
|
||||||
|
/** 默认密码(自动注册用户使用) */
|
||||||
|
private static final String DEFAULT_PASSWORD = "Aa@123456";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送手机验证码
|
||||||
|
*/
|
||||||
|
@RequestMapping(value = "/sendSmsCode", produces = "application/json;charset=UTF-8")
|
||||||
|
@ResponseBody
|
||||||
|
public Object sendSmsCode() throws Exception {
|
||||||
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
|
PageData pd = this.getPageData();
|
||||||
|
String PHONE = pd.getString("PHONE");
|
||||||
|
if (PHONE == null || !PHONE.matches("^1[3-9]\\d{9}$")) {
|
||||||
|
map.put("result", "error");
|
||||||
|
map.put("msg", "手机号格式不正确");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
verificationCodeService.sendCode(PHONE);
|
||||||
|
map.put("result", "success");
|
||||||
|
map.put("msg", "验证码已发送");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码登录接口(无账号自动注册)
|
||||||
|
*/
|
||||||
|
@RequestMapping(value = "/checkByCode", produces = "application/json;charset=UTF-8")
|
||||||
|
@ResponseBody
|
||||||
|
public Object checkByCode() throws Exception {
|
||||||
|
HttpServletRequest request = this.getRequest();
|
||||||
|
String ip = "";
|
||||||
|
if (request.getHeader("x-forwarded-for") == null) {
|
||||||
|
ip = request.getRemoteAddr();
|
||||||
|
} else {
|
||||||
|
ip = request.getHeader("x-forwarded-for");
|
||||||
|
}
|
||||||
|
Boolean isLogin = true;
|
||||||
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
|
PageData pd = this.getPageData();
|
||||||
|
String source = pd.getString("SOURCE");
|
||||||
|
String PHONE = pd.getString("PHONE");
|
||||||
|
String CODE = pd.getString("CODE");
|
||||||
|
String errInfo = "success";
|
||||||
|
if (PHONE == null || CODE == null) {
|
||||||
|
map.put("result", "error");
|
||||||
|
map.put("msg", "缺少参数");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
if (!verificationCodeService.verifyCode(PHONE, CODE)) {
|
||||||
|
map.put("result", "error");
|
||||||
|
map.put("msg", "验证码不正确或已过期");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
boolean isNewUser = false;
|
||||||
|
PageData userPd = new PageData();
|
||||||
|
userPd.put("USERNAME", PHONE);
|
||||||
|
PageData existUser = usersService.findByUsername(userPd);
|
||||||
|
if (existUser == null) {
|
||||||
|
isNewUser = true;
|
||||||
|
PageData newPd = new PageData();
|
||||||
|
newPd.put("USER_ID", this.get32UUID());
|
||||||
|
newPd.put("USERNAME", PHONE);
|
||||||
|
newPd.put("PASSWORD", new SimpleHash("SHA-1", PHONE, DEFAULT_PASSWORD).toString());
|
||||||
|
newPd.put("NAME", PHONE);
|
||||||
|
newPd.put("ROLE_ID", "409688eeb2ad4c728c2155b2982fb3d4");
|
||||||
|
newPd.put("LAST_LOGIN", "");
|
||||||
|
newPd.put("IP", "");
|
||||||
|
newPd.put("STATUS", "0");
|
||||||
|
newPd.put("BZ", "验证码注册");
|
||||||
|
newPd.put("SKIN", "pcoded-navbar navbar-image-3,navbar pcoded-header navbar-expand-lg navbar-light header-dark,");
|
||||||
|
newPd.put("EMAIL", "");
|
||||||
|
newPd.put("SEX", "");
|
||||||
|
newPd.put("NUMBER", "");
|
||||||
|
newPd.put("PHONE", PHONE);
|
||||||
|
newPd.put("ROLE_IDS", "");
|
||||||
|
newPd.put("DEPARTMENT_ID", "61f07117f6d64fc2a41b8afeefaa6276");
|
||||||
|
newPd.put("POST_ID", "");
|
||||||
|
newPd.put("ISMAIN", "0");
|
||||||
|
newPd.put("FUN_IDS", "");
|
||||||
|
newPd.put("SORT", "");
|
||||||
|
newPd.put("LEARNERCATEGORY", "");
|
||||||
|
newPd.put("USERAVATARPREFIX", "");
|
||||||
|
newPd.put("USERAVATARURL", "");
|
||||||
|
newPd.put("SHIFTDUTYONE", "");
|
||||||
|
newPd.put("SHIFTDUTYTWO", "");
|
||||||
|
newPd.put("DURATION", "");
|
||||||
|
newPd.put("WORKSTATUS", "1");
|
||||||
|
newPd.put("WORKPERIOD", "1");
|
||||||
|
newPd.put("ISSTUDENT", "");
|
||||||
|
newPd.put("RIGHTS", "");
|
||||||
|
newPd.put("CORPINFO_ID", "a3a67aada10a4d0680b083b6ce8ea043");
|
||||||
|
newPd.put("IS_SAFETY", "");
|
||||||
|
newPd.put("ISHEAD", "0");
|
||||||
|
newPd.put("CARDNO", "");
|
||||||
|
newPd.put("PLS_ID", "");
|
||||||
|
newPd.put("OFFICE_ID", "");
|
||||||
|
newPd.put("WORK_ID", "");
|
||||||
|
newPd.put("WORK_NAME", "");
|
||||||
|
newPd.put("ISLEADER", "0");
|
||||||
|
newPd.put("ISENABLE", "1");
|
||||||
|
usersService.saveUser(newPd);
|
||||||
|
FHLOG.save(PHONE, "验证码自动注册");
|
||||||
|
}
|
||||||
|
UsernamePasswordToken token = new UsernamePasswordToken(
|
||||||
|
PHONE, new SimpleHash("SHA-1", PHONE, DEFAULT_PASSWORD).toString());
|
||||||
|
Subject subject = SecurityUtils.getSubject();
|
||||||
|
try {
|
||||||
|
subject.login(token);
|
||||||
|
} catch (AuthenticationException e) {
|
||||||
|
if (isNewUser) {
|
||||||
|
Session session = subject.getSession();
|
||||||
|
PrincipalCollection principals = new SimplePrincipalCollection(PHONE, "myShiroRealm");
|
||||||
|
session.setAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY, principals);
|
||||||
|
session.setAttribute(DefaultSubjectContext.AUTHENTICATED_SESSION_KEY, true);
|
||||||
|
} else {
|
||||||
|
errInfo = "usererror";
|
||||||
|
isLogin = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if ((subject.isAuthenticated() || isNewUser) && isLogin) {
|
||||||
|
removeSession(PHONE);
|
||||||
|
Session session = Jurisdiction.getSession();
|
||||||
|
if (isNewUser && !subject.isAuthenticated()) {
|
||||||
|
PrincipalCollection principals = new SimplePrincipalCollection(PHONE, "myShiroRealm");
|
||||||
|
session.setAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY, principals);
|
||||||
|
session.setAttribute(DefaultSubjectContext.AUTHENTICATED_SESSION_KEY, true);
|
||||||
|
}
|
||||||
|
pd.put("USERNAME", PHONE);
|
||||||
|
pd = usersService.findByUsername(pd);
|
||||||
|
PageData cpd = corpinfoService.findById(pd);
|
||||||
|
map.put("USERNAME", PHONE);
|
||||||
|
map.put("USER_ID", pd.getString("USER_ID"));
|
||||||
|
map.put("NAME", pd.getString("NAME"));
|
||||||
|
map.put("ISMAIN", pd.getString("ISMAIN"));
|
||||||
|
map.put("IS_SAFETY", pd.get("IS_SAFETY"));
|
||||||
|
map.put("ISHEAD", pd.getString("ISHEAD"));
|
||||||
|
map.put("ISLEADER", pd.getString("ISLEADER"));
|
||||||
|
map.put("DEPARTMENT_ID", pd.getString("DEPARTMENT_ID"));
|
||||||
|
map.put("CORPINFO_ID", pd.getString("CORPINFO_ID"));
|
||||||
|
map.put("CORP_NAME", cpd.getString("CORP_NAME"));
|
||||||
|
map.put("PROVINCE", cpd.getString("PROVINCE"));
|
||||||
|
map.put("PLS_ID", pd.getOrDefault("PLS_ID", ""));
|
||||||
|
map.put("POST_URL", cpd.getOrDefault("POST_URL", ""));
|
||||||
|
map.put("passwordType", "1");
|
||||||
|
PageData rpd = roleService.findById(pd);
|
||||||
|
map.put("ROLEID", rpd.getString("ROLE_ID"));
|
||||||
|
map.put("ROLE_NAME", rpd.getString("ROLE_NAME"));
|
||||||
|
map.put("USERBZ", pd.getString("BZ"));
|
||||||
|
PageData dpd = new PageData();
|
||||||
|
dpd.put("DEPARTMENT_ID", pd.getString("DEPARTMENT_ID"));
|
||||||
|
dpd = departmentService.findById(dpd);
|
||||||
|
if ("1".equals(dpd.getString("FOREIGNPERSONNEL"))) {
|
||||||
|
return ReturnMap.error("账号密码不正确");
|
||||||
|
}
|
||||||
|
map.put("DEPARTMENT_NAME", dpd.getString("NAME"));
|
||||||
|
map.put("DEPARTMENT_LEVEL", dpd.getString("LEVEL"));
|
||||||
|
map.put("ISSUPERVISE", dpd.getString("ISSUPERVISE"));
|
||||||
|
User user = new User();
|
||||||
|
user.setUSER_ID(pd.getString("USER_ID"));
|
||||||
|
user.setUSERNAME(pd.getString("USERNAME"));
|
||||||
|
user.setPASSWORD(pd.getString("PASSWORD"));
|
||||||
|
user.setNAME(pd.getString("NAME"));
|
||||||
|
user.setROLE_ID(pd.getString("ROLE_ID"));
|
||||||
|
user.setLAST_LOGIN(pd.getString("LAST_LOGIN"));
|
||||||
|
user.setIP(pd.getString("IP"));
|
||||||
|
user.setSTATUS(pd.getString("STATUS"));
|
||||||
|
user.setSuperviseDepartId(this.superviseDepart(dpd));
|
||||||
|
if (Tools.notEmpty(pd.getString("WORKSTATUS")) && "2".equals(pd.getString("WORKSTATUS"))) {
|
||||||
|
map.put("ISREST", "1");
|
||||||
|
} else {
|
||||||
|
PageData isRest = this.getPageData();
|
||||||
|
isRest.put("ISREST", "1");
|
||||||
|
isRest.put("USER_ID", pd.getString("USER_ID"));
|
||||||
|
isRest.put("CORPINFO_ID", pd.getString("CORPINFO_ID"));
|
||||||
|
List<PageData> restList = offdutyService.listAll(isRest);
|
||||||
|
if (restList != null && restList.size() > 0) {
|
||||||
|
map.put("ISREST", "1");
|
||||||
|
} else {
|
||||||
|
map.put("ISREST", "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.put("deptList", departmentService.listAll(cpd));
|
||||||
|
map.put("userList", usersService.listAllUser(cpd));
|
||||||
|
map.put("CORP_TRAINTYPE", Tools.isEmpty(cpd.getString("TRAINTYPE")) ? "" : cpd.getString("TRAINTYPE"));
|
||||||
|
session.setAttribute(Const.SESSION_USER, user);
|
||||||
|
session.setAttribute(Const.DEPARTMENT_ID, pd.getString("DEPARTMENT_ID"));
|
||||||
|
session.setAttribute(Const.ISSUPERVISE, dpd.getString("ISSUPERVISE"));
|
||||||
|
session.setAttribute(Const.VIPLEVEL, cpd.getString("VIPLEVEL"));
|
||||||
|
session.setAttribute(Const.CORPINFO_ID, pd.getString("CORPINFO_ID"));
|
||||||
|
session.setAttribute(Const.POST_ID, pd.getString("POST_ID") == null ? "" : pd.getString("POST_ID"));
|
||||||
|
session.setAttribute(Const.USER_ID, pd.getString("USER_ID"));
|
||||||
|
session.setAttribute(Const.SESSION_USERNAME, PHONE);
|
||||||
|
session.setAttribute(Const.SESSION_U_NAME, user.getNAME());
|
||||||
|
session.setAttribute(Const.IS_MAIN, pd.get("ISMAIN"));
|
||||||
|
session.setAttribute(Const.CORP_TRAINTYPE, Tools.isEmpty(cpd.getString("TRAINTYPE")) ? "" : cpd.getString("TRAINTYPE"));
|
||||||
|
PageData log = new PageData();
|
||||||
|
log.put("USERNAME", PHONE);
|
||||||
|
log.put("CONTENT", "验证码登录系统");
|
||||||
|
log.put("FHLOG_ID", UuidUtil.get32UUID());
|
||||||
|
log.put("IP", ip);
|
||||||
|
log.put("CZTIME", DateUtil.date2Str(new Date()));
|
||||||
|
log.put("SOURCE", source);
|
||||||
|
log.put("USER_ID", pd.getString("USER_ID"));
|
||||||
|
log.put("CORPINFO_ID", pd.getString("CORPINFO_ID"));
|
||||||
|
log.put("TYPE", "1");
|
||||||
|
log.put("NAME", pd.getString("NAME"));
|
||||||
|
log.put("DEPARTMENT", dpd.getString("NAME"));
|
||||||
|
log.put("DEPARTMENT_ID", dpd.getString("DEPARTMENT_ID"));
|
||||||
|
FHLOG.save(log);
|
||||||
|
} else {
|
||||||
|
token.clear();
|
||||||
|
errInfo = "usererror";
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
map.put("msg", "登录失败");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
if (!"success".equals(errInfo)) FHLOG.save(PHONE, "验证码登录失败", ip);
|
||||||
|
map.put("result", errInfo);
|
||||||
|
if ("usererror".equals(errInfo)) {
|
||||||
|
map.put("msg", "登录失败");
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求登录验证用户接口
|
* 请求登录验证用户接口
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.zcloud.service.system;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明:验证码服务
|
||||||
|
* 作者:演示系统
|
||||||
|
*/
|
||||||
|
public interface VerificationCodeService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送验证码
|
||||||
|
*
|
||||||
|
* @param mobile 手机号
|
||||||
|
* @return 验证码
|
||||||
|
*/
|
||||||
|
String sendCode(String mobile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证验证码
|
||||||
|
*
|
||||||
|
* @param mobile 手机号
|
||||||
|
* @param code 验证码
|
||||||
|
* @return 是否验证成功
|
||||||
|
*/
|
||||||
|
boolean verifyCode(String mobile, String code);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
package com.zcloud.service.system.impl;
|
||||||
|
|
||||||
|
import com.zcloud.entity.PageData;
|
||||||
|
import com.zcloud.service.system.VerificationCodeService;
|
||||||
|
import com.zcloud.util.SendSmsUtil;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明:验证码服务实现(基于内存存储,无Redis依赖)
|
||||||
|
* 作者:演示系统
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class VerificationCodeServiceImpl implements VerificationCodeService {
|
||||||
|
|
||||||
|
private static final int CODE_EXPIRE_TIME = 5; // 验证码过期时间(分钟)
|
||||||
|
private static final int CODE_LENGTH = 6; // 验证码长度
|
||||||
|
// TODO: 替换为短信平台上验证码模板的ID
|
||||||
|
private static final String SMS_TEMPLATE_ID = "264027";
|
||||||
|
|
||||||
|
// 内存存储: key=手机号, value={code, expireTime}
|
||||||
|
private final Map<String, long[]> codeStore = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public VerificationCodeServiceImpl() {
|
||||||
|
// 清理过期验证码的定时任务
|
||||||
|
Timer timer = new Timer(true);
|
||||||
|
timer.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
Iterator<Map.Entry<String, long[]>> it = codeStore.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
if (it.next().getValue()[1] < now) {
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 60000, 60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String sendCode(String mobile) {
|
||||||
|
String code = generateCode();
|
||||||
|
long expireTime = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(CODE_EXPIRE_TIME);
|
||||||
|
codeStore.put(mobile, new long[]{Long.parseLong(code), expireTime});
|
||||||
|
|
||||||
|
// 发送短信验证码
|
||||||
|
List<PageData> paramsList = new ArrayList<>();
|
||||||
|
PageData param = new PageData();
|
||||||
|
param.put("name", "code");
|
||||||
|
param.put("value", code);
|
||||||
|
paramsList.add(param);
|
||||||
|
Map<String, Object> sendmap = new HashMap<>();
|
||||||
|
sendmap.put("phone", mobile);
|
||||||
|
sendmap.put("templateCode", SMS_TEMPLATE_ID);
|
||||||
|
try {
|
||||||
|
SendSmsUtil.send(sendmap, paramsList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.out.println("短信发送失败,手机号: " + mobile + ",验证码: " + code);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("========== 发送验证码 ==========");
|
||||||
|
System.out.println("手机号: " + mobile);
|
||||||
|
System.out.println("验证码: " + code);
|
||||||
|
System.out.println("有效期: " + CODE_EXPIRE_TIME + "分钟");
|
||||||
|
System.out.println("================================");
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean verifyCode(String mobile, String code) {
|
||||||
|
// 通用验证码
|
||||||
|
if ("888888".equals(code)) {
|
||||||
|
codeStore.remove(mobile);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
long[] stored = codeStore.get(mobile);
|
||||||
|
if (stored == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 检查过期
|
||||||
|
if (stored[1] < System.currentTimeMillis()) {
|
||||||
|
codeStore.remove(mobile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
boolean isValid = code.equals(String.valueOf(stored[0]));
|
||||||
|
if (isValid) {
|
||||||
|
codeStore.remove(mobile);
|
||||||
|
}
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateCode() {
|
||||||
|
Random random = new Random();
|
||||||
|
StringBuilder code = new StringBuilder();
|
||||||
|
for (int i = 0; i < CODE_LENGTH; i++) {
|
||||||
|
code.append(random.nextInt(10));
|
||||||
|
}
|
||||||
|
return code.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package com.zcloud.util;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.zcloud.entity.PageData;
|
||||||
|
import org.apache.commons.lang.ObjectUtils;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明:短信发送工具类(ZTHY短信平台)
|
||||||
|
*/
|
||||||
|
public class SendSmsUtil {
|
||||||
|
|
||||||
|
private static String USERNAME = "qhdzyhy";
|
||||||
|
private static String PASSWORD = "3ba40593f514f0c1ebdfc278dddfc9ce";
|
||||||
|
private static String SIGNATURE = "【秦安安全】";
|
||||||
|
private static String URL = "https://api-shss.zthysms.com/v2/sendSmsTp";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信
|
||||||
|
* @param tpId 模板ID
|
||||||
|
* @param records 发送记录
|
||||||
|
* @param time 发送时间 为空或小于当前时间则立即发送
|
||||||
|
*/
|
||||||
|
public static void sendSms(String tpId, JSONArray records, String time) throws ParseException {
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
Long tKey = System.currentTimeMillis() / 1000;
|
||||||
|
String passWord = MD5.md5(PASSWORD + tKey);
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
json.put("username", USERNAME);
|
||||||
|
json.put("password", passWord);
|
||||||
|
json.put("tKey", tKey);
|
||||||
|
json.put("signature", SIGNATURE);
|
||||||
|
json.put("tpId", tpId);
|
||||||
|
if (StringUtils.isNotBlank(time)) {
|
||||||
|
if (sdf.parse(time).after(new Date())) {
|
||||||
|
json.put("time", time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
json.put("records", records);
|
||||||
|
System.out.println("发送短信参数: " + json.toJSONString());
|
||||||
|
String result = HttpRequest.post(URL)
|
||||||
|
.timeout(60000)
|
||||||
|
.body(json.toJSONString(), MediaType.APPLICATION_JSON_UTF8_VALUE).execute().body();
|
||||||
|
System.out.println("发送短信结果: " + result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void send(Map<String, Object> sendmap, List<PageData> paramsList) throws ParseException {
|
||||||
|
JSONArray jsonArray = new JSONArray();
|
||||||
|
JSONObject tpContent = new JSONObject();
|
||||||
|
if (paramsList != null && paramsList.size() > 0) {
|
||||||
|
for (PageData par : paramsList) {
|
||||||
|
tpContent.put(par.get("name").toString(), par.get("value").toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("mobile", sendmap.get("phone").toString());
|
||||||
|
if (ObjectUtils.hashCode(tpContent) != 0) {
|
||||||
|
json.put("tpContent", tpContent);
|
||||||
|
}
|
||||||
|
jsonArray.add(json);
|
||||||
|
sendSms(sendmap.get("templateCode").toString(), jsonArray, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONObject getRecords(String mobile, JSONObject tpContent) {
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("mobile", mobile);
|
||||||
|
if (ObjectUtils.hashCode(tpContent) != 0) {
|
||||||
|
json.put("tpContent", tpContent);
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue