Compare commits
2 Commits
a1b880f817
...
06b8a4f128
| Author | SHA1 | Date | |
|---|---|---|---|
| 06b8a4f128 | |||
| fd4ab146e0 |
@@ -84,6 +84,27 @@ public class SysLoginController
|
|||||||
return ajax;
|
return ajax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过微信获取手机号和验证码
|
||||||
|
* @param loginBody
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/app/appWxphone")
|
||||||
|
public AjaxResult appWxphone(@RequestBody LoginBody loginBody)
|
||||||
|
{
|
||||||
|
AjaxResult ajax = AjaxResult.success();
|
||||||
|
ajax=loginService.getWxPhone(loginBody);
|
||||||
|
return ajax;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/app/appLoginPhone")
|
||||||
|
public AjaxResult appLoginPhone(@RequestBody LoginBody loginBody)
|
||||||
|
{
|
||||||
|
AjaxResult ajax = AjaxResult.success();
|
||||||
|
ajax=loginService.appLoginTwo(loginBody);
|
||||||
|
return ajax;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一体机身份证登录
|
* 一体机身份证登录
|
||||||
* @param loginBody
|
* @param loginBody
|
||||||
|
|||||||
@@ -165,6 +165,15 @@ wx:
|
|||||||
appid: wx4aa34488b965a331
|
appid: wx4aa34488b965a331
|
||||||
secret: 558780ecc2750f87e556b0e5496773c9
|
secret: 558780ecc2750f87e556b0e5496773c9
|
||||||
|
|
||||||
|
#短信服务
|
||||||
|
sms:
|
||||||
|
#API密钥账号
|
||||||
|
secretName: kszhjyrcjt
|
||||||
|
#API密钥
|
||||||
|
secretKey: Dwhc9c0IiHecvC5D
|
||||||
|
#短信模板ID
|
||||||
|
templateId: 37446
|
||||||
|
|
||||||
#统一门户认证
|
#统一门户认证
|
||||||
oauth:
|
oauth:
|
||||||
#客户端的ID
|
#客户端的ID
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//package com.ruoyi.cms.handler;
|
//package com.ruoyi.cms.handler;
|
||||||
//
|
//
|
||||||
//import com.ruoyi.cms.util.AliyunNlsUtils;
|
//import com.ruoyi.common.utils.aliyun.AliyunNlsUtils;
|
||||||
//import org.springframework.stereotype.Component;
|
//import org.springframework.stereotype.Component;
|
||||||
//
|
//
|
||||||
//import javax.websocket.*;
|
//import javax.websocket.*;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import com.alibaba.nls.client.protocol.SampleRateEnum;
|
|||||||
import com.alibaba.nls.client.protocol.asr.SpeechRecognizer;
|
import com.alibaba.nls.client.protocol.asr.SpeechRecognizer;
|
||||||
import com.alibaba.nls.client.protocol.asr.SpeechRecognizerListener;
|
import com.alibaba.nls.client.protocol.asr.SpeechRecognizerListener;
|
||||||
import com.alibaba.nls.client.protocol.asr.SpeechRecognizerResponse;
|
import com.alibaba.nls.client.protocol.asr.SpeechRecognizerResponse;
|
||||||
import com.ruoyi.cms.util.AliyunNlsUtils;
|
import com.ruoyi.common.utils.aliyun.AliyunNlsUtils;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
//import com.alibaba.nls.client.protocol.tts.SpeechSynthesizer;
|
//import com.alibaba.nls.client.protocol.tts.SpeechSynthesizer;
|
||||||
//import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerListener;
|
//import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerListener;
|
||||||
//import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerResponse;
|
//import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerResponse;
|
||||||
//import com.ruoyi.cms.util.AliyunNlsUtils;
|
//import com.ruoyi.common.utils.aliyun.AliyunNlsUtils;
|
||||||
//import org.slf4j.Logger;
|
//import org.slf4j.Logger;
|
||||||
//import org.slf4j.LoggerFactory;
|
//import org.slf4j.LoggerFactory;
|
||||||
//import org.springframework.stereotype.Component;
|
//import org.springframework.stereotype.Component;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.common.utils.aliyun.AliyunNlsUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<include refid="selectOperLogVo"/>
|
<include refid="selectOperLogVo"/>
|
||||||
<where>
|
<where>
|
||||||
<if test="operIp != null and operIp != ''">
|
<if test="operIp != null and operIp != ''">
|
||||||
AND oper_ip like concat('%', #{operIp}, '%')
|
AND oper_ip like concat('%', CAST(#{operIp} AS VARCHAR), '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="title != null and title != ''">
|
<if test="title != null and title != ''">
|
||||||
AND title like concat('%', #{title}, '%')
|
AND title like concat('%', CAST(#{title} AS VARCHAR), '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="businessType != null">
|
<if test="businessType != null">
|
||||||
AND business_type = #{businessType}
|
AND business_type = #{businessType}
|
||||||
@@ -58,7 +58,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
AND status = #{status}
|
AND status = #{status}
|
||||||
</if>
|
</if>
|
||||||
<if test="operName != null and operName != ''">
|
<if test="operName != null and operName != ''">
|
||||||
AND oper_name like concat('%', #{operName}, '%')
|
AND oper_name like concat('%', CAST(#{operName} AS VARCHAR), '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
AND oper_time >= #{params.beginTime}
|
AND oper_time >= #{params.beginTime}
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package com.ruoyi.common.config;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.core.domain.entity.SmsRequestDTO;
|
||||||
|
import com.ruoyi.common.utils.aliyun.AliyunNlsUtils;
|
||||||
|
import com.ruoyi.common.utils.http.HttpUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SmsRequestClient {
|
||||||
|
|
||||||
|
private static final int LIMIT = 10; // 每秒允许10次请求
|
||||||
|
private static final long REFRESH_PERIOD = 1000; // 1秒刷新
|
||||||
|
private final AtomicInteger tokenBucket = new AtomicInteger(LIMIT);
|
||||||
|
private final AtomicLong lastRefreshTime = new AtomicLong(System.currentTimeMillis());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API密钥账号
|
||||||
|
*/
|
||||||
|
@Value("${sms.secretName}")
|
||||||
|
private String secretName;
|
||||||
|
/**
|
||||||
|
* API密钥
|
||||||
|
*/
|
||||||
|
@Value("${sms.secretKey}")
|
||||||
|
private String secretKey;
|
||||||
|
/**
|
||||||
|
* 短信模板ID
|
||||||
|
*/
|
||||||
|
@Value("${sms.templateId}")
|
||||||
|
private String templateId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信
|
||||||
|
* @param requestDTO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public AjaxResult sendSms(SmsRequestDTO requestDTO){
|
||||||
|
|
||||||
|
if (!tryAcquireToken()) {
|
||||||
|
return AjaxResult.error("发送失败:当前发送人数过多,请稍后重试");
|
||||||
|
}
|
||||||
|
|
||||||
|
//参数
|
||||||
|
requestDTO.setSecretName(secretName);
|
||||||
|
requestDTO.setSecretKey(secretKey);
|
||||||
|
requestDTO.setTemplateId(templateId);
|
||||||
|
|
||||||
|
String msg="";
|
||||||
|
try {
|
||||||
|
String json= JSON.toJSONString(requestDTO);
|
||||||
|
String result= HttpUtils.snedSmsPost(AliyunNlsUtils.getSmsUrl(),json);
|
||||||
|
JSONObject responseJson = JSONObject.parseObject(result);
|
||||||
|
System.out.println("调用返回===="+responseJson);
|
||||||
|
msg = responseJson.getString("msg");
|
||||||
|
System.out.println("返回消息"+msg);
|
||||||
|
if (!"0".equals(responseJson.getString("code"))) {
|
||||||
|
msg="发送失败:" + msg;
|
||||||
|
return AjaxResult.error(msg);
|
||||||
|
}else{
|
||||||
|
msg="发送成功:" + msg;
|
||||||
|
return AjaxResult.success(msg);
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
return AjaxResult.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean tryAcquireToken() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
// 刷新令牌桶
|
||||||
|
if (now - lastRefreshTime.get() >= REFRESH_PERIOD) {
|
||||||
|
tokenBucket.set(LIMIT);
|
||||||
|
lastRefreshTime.set(now);
|
||||||
|
}
|
||||||
|
// 尝试获取令牌
|
||||||
|
return tokenBucket.decrementAndGet() >= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.ruoyi.common.core.domain.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class SmsRequestDTO {
|
||||||
|
/**
|
||||||
|
* name
|
||||||
|
*/
|
||||||
|
private String secretName;
|
||||||
|
/**
|
||||||
|
* key
|
||||||
|
*/
|
||||||
|
private String secretKey;
|
||||||
|
/**
|
||||||
|
* 手机号码,多个号码请用英文逗号隔开
|
||||||
|
*/
|
||||||
|
private String mobile;
|
||||||
|
/**
|
||||||
|
* 短信内容,请保持在500字以内。注意:使用短信模板进行提交时,请填写模板拼接后的完整内容。
|
||||||
|
* 方式一:
|
||||||
|
* {"SecretName":"API","SecretKey":"000000","TimeStamp":null,"Mobile":"13000000000","Content":"你好,你的验证码是541254,有效期5分钟。","TemplateId":"","ExtCode":"","SignName":"","Timing":"","CustomId":""}
|
||||||
|
* 方式二:
|
||||||
|
* {"SecretName":"API","SecretKey":"000000","TimeStamp":null,"Mobile":"13000000000","Content":"","TemplateId":"000000","TemplateVars":["541254","5"],"ExtCode":"","SignName":"","Timing":"","CustomId":""}
|
||||||
|
*/
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板id
|
||||||
|
*/
|
||||||
|
private String templateId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信模板变量集合,集合中数据类型为String
|
||||||
|
*/
|
||||||
|
private String[] templateVars;
|
||||||
|
}
|
||||||
@@ -47,7 +47,29 @@ public class LoginBody
|
|||||||
/**
|
/**
|
||||||
* 企业类型
|
* 企业类型
|
||||||
*/
|
*/
|
||||||
public String orgType;
|
private String orgType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号验证码
|
||||||
|
*/
|
||||||
|
private String smsCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号
|
||||||
|
*/
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信openid
|
||||||
|
*/
|
||||||
|
private String openid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信unionid
|
||||||
|
*/
|
||||||
|
private String unionid;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getUsername()
|
public String getUsername()
|
||||||
{
|
{
|
||||||
@@ -128,4 +150,36 @@ public class LoginBody
|
|||||||
public void setOrgType(String orgType) {
|
public void setOrgType(String orgType) {
|
||||||
this.orgType = orgType;
|
this.orgType = orgType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSmsCode() {
|
||||||
|
return smsCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmsCode(String smsCode) {
|
||||||
|
this.smsCode = smsCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhone(String phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOpenid() {
|
||||||
|
return openid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOpenid(String openid) {
|
||||||
|
this.openid = openid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUnionid() {
|
||||||
|
return unionid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnionid(String unionid) {
|
||||||
|
this.unionid = unionid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.ruoyi.common.core.redis;
|
||||||
|
|
||||||
|
public class RedisUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信key
|
||||||
|
*/
|
||||||
|
public static final String SMS_CODE_KEY="login:sms:code:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信lock
|
||||||
|
*/
|
||||||
|
public static final String SMS_SEND_LOCK="login:sms:lock:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码有效期 5分钟
|
||||||
|
*/
|
||||||
|
public static final Integer SMS_EXPIRE = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 冷却时间
|
||||||
|
*/
|
||||||
|
public static final Integer LOCK_EXPIRE = 60;;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.ruoyi.cms.util;
|
package com.ruoyi.common.utils.aliyun;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 阿里云配置
|
* 阿里云配置
|
||||||
@@ -22,6 +22,11 @@ public class AliyunNlsUtils {
|
|||||||
*/
|
*/
|
||||||
public static final String NLS_FORMAL_URL="http://192.168.2.102:10044";
|
public static final String NLS_FORMAL_URL="http://192.168.2.102:10044";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试短短地址
|
||||||
|
*/
|
||||||
|
public static final String SMS_TEST_URL="https://api.028lk.com/Sms/Api/Send";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据环境判断正式还是测试
|
* 根据环境判断正式还是测试
|
||||||
* @return
|
* @return
|
||||||
@@ -41,4 +46,14 @@ public class AliyunNlsUtils {
|
|||||||
System.out.println("微信授权登录当前环境:" + (USE_TEST_ENV ? "测试" : "正式") + ",获取oppenid地址:" + url);
|
System.out.println("微信授权登录当前环境:" + (USE_TEST_ENV ? "测试" : "正式") + ",获取oppenid地址:" + url);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信验证码地址
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getSmsUrl(){
|
||||||
|
String url = USE_TEST_ENV ? SMS_TEST_URL : NLS_FORMAL_URL+"/ksSend";
|
||||||
|
System.out.println("短信地址当前环境:" + (USE_TEST_ENV ? "测试" : "正式") + ",sms地址:" + url);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,7 @@
|
|||||||
package com.ruoyi.common.utils.http;
|
package com.ruoyi.common.utils.http;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
import java.net.*;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.net.ConnectException;
|
|
||||||
import java.net.SocketTimeoutException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import javax.net.ssl.HostnameVerifier;
|
import javax.net.ssl.HostnameVerifier;
|
||||||
@@ -244,6 +237,78 @@ public class HttpUtils
|
|||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String snedSmsPost(String httpUrl, String data) {
|
||||||
|
|
||||||
|
HttpURLConnection connection = null;
|
||||||
|
InputStream inputStream = null;
|
||||||
|
OutputStream outputStream = null;
|
||||||
|
BufferedReader bufferedReader = null;
|
||||||
|
String result = null;
|
||||||
|
try {
|
||||||
|
URL url = new URL(httpUrl);
|
||||||
|
// 通过远程url连接对象打开连接
|
||||||
|
connection = (HttpURLConnection) url.openConnection();
|
||||||
|
// 设置连接请求方式
|
||||||
|
connection.setRequestMethod("POST");
|
||||||
|
// 设置连接主机服务器超时时间:15000毫秒
|
||||||
|
connection.setConnectTimeout(15000);
|
||||||
|
// 设置读取主机服务器返回数据超时时间:60000毫秒
|
||||||
|
connection.setReadTimeout(60000);
|
||||||
|
// 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
// 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
|
||||||
|
connection.setRequestProperty("Content-Type", "application/json");
|
||||||
|
// 通过连接对象获取一个输出流
|
||||||
|
outputStream = connection.getOutputStream();
|
||||||
|
// 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
|
||||||
|
outputStream.write(data.getBytes());
|
||||||
|
// 通过连接对象获取一个输入流,向远程读取
|
||||||
|
if (connection.getResponseCode() == 200) {
|
||||||
|
inputStream = connection.getInputStream();
|
||||||
|
// 对输入流对象进行包装:charset根据工作项目组的要求来设置
|
||||||
|
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
|
||||||
|
StringBuffer stringBuffer = new StringBuffer();
|
||||||
|
String temp = null;
|
||||||
|
// 循环遍历一行一行读取数据
|
||||||
|
while ((temp = bufferedReader.readLine()) != null) {
|
||||||
|
stringBuffer.append(temp);
|
||||||
|
stringBuffer.append("\r\n");
|
||||||
|
}
|
||||||
|
result = stringBuffer.toString();
|
||||||
|
}
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
// 关闭资源
|
||||||
|
if (null != bufferedReader) {
|
||||||
|
try {
|
||||||
|
bufferedReader.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (null != outputStream) {
|
||||||
|
try {
|
||||||
|
outputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (null != inputStream) {
|
||||||
|
try {
|
||||||
|
inputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 断开与远程地址url的连接
|
||||||
|
connection.disconnect();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private static class TrustAnyTrustManager implements X509TrustManager
|
private static class TrustAnyTrustManager implements X509TrustManager
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.ruoyi.framework.web.service;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.RandomUtil;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.ruoyi.cms.domain.vo.WechatAuthVO;
|
import com.ruoyi.cms.domain.vo.WechatAuthVO;
|
||||||
@@ -9,12 +10,15 @@ import com.ruoyi.cms.service.IAppUserService;
|
|||||||
import com.ruoyi.cms.util.StringUtil;
|
import com.ruoyi.cms.util.StringUtil;
|
||||||
import com.ruoyi.cms.util.WechatUtil;
|
import com.ruoyi.cms.util.WechatUtil;
|
||||||
import com.ruoyi.cms.util.encrypt.QuickValidUtils;
|
import com.ruoyi.cms.util.encrypt.QuickValidUtils;
|
||||||
|
import com.ruoyi.common.config.SmsRequestClient;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.entity.AppUser;
|
import com.ruoyi.common.core.domain.entity.AppUser;
|
||||||
|
import com.ruoyi.common.core.domain.entity.SmsRequestDTO;
|
||||||
import com.ruoyi.common.core.domain.model.LoginBody;
|
import com.ruoyi.common.core.domain.model.LoginBody;
|
||||||
import com.ruoyi.common.core.domain.model.LoginSiteUser;
|
import com.ruoyi.common.core.domain.model.LoginSiteUser;
|
||||||
import com.ruoyi.common.core.domain.model.RegisterBody;
|
import com.ruoyi.common.core.domain.model.RegisterBody;
|
||||||
import com.ruoyi.common.core.redis.DistributedLockUtil;
|
import com.ruoyi.common.core.redis.DistributedLockUtil;
|
||||||
|
import com.ruoyi.common.core.redis.RedisUtils;
|
||||||
import com.ruoyi.common.utils.*;
|
import com.ruoyi.common.utils.*;
|
||||||
import com.ruoyi.framework.web.exception.ParamErrorConstants;
|
import com.ruoyi.framework.web.exception.ParamErrorConstants;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -77,6 +81,8 @@ public class SysLoginService
|
|||||||
private IAppUserService appUserService;
|
private IAppUserService appUserService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private DistributedLockUtil distributedLockUtil;
|
private DistributedLockUtil distributedLockUtil;
|
||||||
|
@Autowired
|
||||||
|
private SmsRequestClient smsRequestClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录验证
|
* 登录验证
|
||||||
@@ -321,6 +327,168 @@ public class SysLoginService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过微信授权登录获取手机号
|
||||||
|
* @param dto
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public AjaxResult getWxPhone(LoginBody dto){
|
||||||
|
AjaxResult validateResult = validateBaseParam(dto);
|
||||||
|
if (validateResult != null) {
|
||||||
|
return validateResult;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
WechatAuthVO wechatAuthVO = getWechatAuthInfo(dto.getCode());
|
||||||
|
if (wechatAuthVO == null) {
|
||||||
|
System.err.println("微信授权返回null");
|
||||||
|
return AjaxResult.error("微信授权失败");
|
||||||
|
}
|
||||||
|
String openid = wechatAuthVO.getOpenid();
|
||||||
|
String unionid = wechatAuthVO.getUnionid();
|
||||||
|
String sessionKey = wechatAuthVO.getSessionKey();
|
||||||
|
if (StringUtils.isEmpty(openid)) {
|
||||||
|
System.err.println("微信授权返回openid为空");
|
||||||
|
return AjaxResult.error("微信授权失败");
|
||||||
|
}
|
||||||
|
//解密获取手机号
|
||||||
|
String phone = decryptPhone(dto, sessionKey);
|
||||||
|
if (phone == null) {
|
||||||
|
System.err.println("手机号解密失败,openid=" + openid);
|
||||||
|
return AjaxResult.error("获取手机号失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
//发送短信,并缓存
|
||||||
|
AjaxResult smsResult=sendSmsAndCache(phone);
|
||||||
|
if (!smsResult.isSuccess()) {
|
||||||
|
return smsResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
AjaxResult ajax = AjaxResult.success("获取手机号成功");
|
||||||
|
ajax.put("phone", phone);
|
||||||
|
ajax.put("openid",openid);
|
||||||
|
ajax.put("unionid",unionid);
|
||||||
|
return ajax;
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("获取手机号异常:" + e.getMessage());
|
||||||
|
return AjaxResult.error("获取手机号异常,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信并缓存
|
||||||
|
* @param phone
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private AjaxResult sendSmsAndCache(String phone) {
|
||||||
|
if (Boolean.TRUE.equals(redisCache.hasKey(RedisUtils.SMS_SEND_LOCK + phone))) {
|
||||||
|
return AjaxResult.error("验证码发送频繁,请60秒后重试");
|
||||||
|
}
|
||||||
|
// 生成6位验证码
|
||||||
|
String code = RandomUtil.randomNumbers(6);
|
||||||
|
// 缓存验证码
|
||||||
|
redisCache.setCacheObject(RedisUtils.SMS_CODE_KEY + phone, code, RedisUtils.SMS_EXPIRE, TimeUnit.MINUTES);
|
||||||
|
// 缓存发送锁(防重)
|
||||||
|
redisCache.setCacheObject(RedisUtils.SMS_SEND_LOCK + phone, 1, RedisUtils.LOCK_EXPIRE, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
try {
|
||||||
|
SmsRequestDTO requestDTO=new SmsRequestDTO();
|
||||||
|
requestDTO.setMobile(phone);
|
||||||
|
String[] tmpValues={code,String.valueOf(RedisUtils.SMS_EXPIRE)};
|
||||||
|
requestDTO.setTemplateVars(tmpValues);
|
||||||
|
AjaxResult result=smsRequestClient.sendSms(requestDTO);
|
||||||
|
//判断是否成功
|
||||||
|
if(!result.isSuccess()){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
System.out.println("短信发送成功 → phone=" + phone + ",code=" + code);
|
||||||
|
return AjaxResult.success("验证码发送成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 发送失败,删除缓存
|
||||||
|
redisCache.deleteObject(RedisUtils.SMS_CODE_KEY + phone);
|
||||||
|
redisCache.deleteObject(RedisUtils.SMS_SEND_LOCK + phone);
|
||||||
|
System.err.println("短信发送失败:" + e.getMessage());
|
||||||
|
return AjaxResult.error("短信发送失败,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码-验证
|
||||||
|
* @param phone
|
||||||
|
* @param smsCode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public AjaxResult checkSmsCode(String phone, String smsCode) {
|
||||||
|
if (StringUtils.isBlank(smsCode)) {
|
||||||
|
return AjaxResult.error("请输入验证码");
|
||||||
|
}
|
||||||
|
|
||||||
|
String cacheCode = redisCache.getCacheObject(RedisUtils.SMS_CODE_KEY + phone);
|
||||||
|
if (cacheCode == null) {
|
||||||
|
return AjaxResult.error("验证码已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cacheCode.equals(smsCode.trim())) {
|
||||||
|
return AjaxResult.error("验证码错误");
|
||||||
|
}
|
||||||
|
// 验证通过,删除
|
||||||
|
redisCache.deleteObject(RedisUtils.SMS_CODE_KEY + phone);
|
||||||
|
redisCache.deleteObject(RedisUtils.SMS_SEND_LOCK + phone);
|
||||||
|
return AjaxResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序登录主逻辑
|
||||||
|
* 核心逻辑:优先处理网格员(is_company_user=2),再处理普通招聘者/求职者
|
||||||
|
*/
|
||||||
|
public AjaxResult appLoginTwo(LoginBody dto) {
|
||||||
|
// 1. 验证基础参数(前端userType仅0/1,拦截非法参数)
|
||||||
|
AjaxResult validateResult = validateBaseParam(dto);
|
||||||
|
if (validateResult != null) {
|
||||||
|
return validateResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
//添加验证码验证
|
||||||
|
AjaxResult smsValid = checkSmsCode(dto.getPhone(), dto.getSmsCode());
|
||||||
|
if (!smsValid.isSuccess()) {
|
||||||
|
return smsValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 3. 第一步:通过OpenID优先查询网格员(无需解密手机号,效率更高)
|
||||||
|
AppUser openidSpecialUser = appUserService.selectByOpenid(dto.getOpenid(), StringUtil.IS_GRID_USER);
|
||||||
|
if (openidSpecialUser != null) {
|
||||||
|
System.out.printf("小程序登录-匹配到OpenID网格员:openid=%s, phone=%s%n",
|
||||||
|
openidSpecialUser.getOpenid(), openidSpecialUser.getPhone());
|
||||||
|
return handleSpecialUserLogin(openidSpecialUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 第二步:通过手机号查询网格员(OpenID未匹配时兜底)
|
||||||
|
AppUser phoneSpecialUser = appUserService.getPhoneAndUserType(dto.getPhone(), StringUtil.IS_GRID_USER);
|
||||||
|
if (phoneSpecialUser != null) {
|
||||||
|
System.out.printf("小程序登录-匹配到手机号网格员:phone=%s, openid=%s%n",
|
||||||
|
phoneSpecialUser.getPhone(), phoneSpecialUser.getOpenid());
|
||||||
|
return handleSpecialUserLogin(phoneSpecialUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 非网格员:处理普通用户(招聘者/求职者)登录逻辑
|
||||||
|
String userType = dto.getUserType();
|
||||||
|
// 6.1 优先匹配「OpenID+前端传入角色」的老用户
|
||||||
|
AppUser existingUser = appUserService.selectByOpenid(dto.getOpenid(), userType);
|
||||||
|
if (existingUser != null) {
|
||||||
|
System.out.printf("小程序登录-匹配到普通老用户:openid=%s, userType=%s%n", dto.getOpenid(), userType, dto.getOrgType());
|
||||||
|
return handleExistingUser(existingUser, userType,dto.getOrgType());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6.2 处理普通用户的匹配与注册(手机号绑定、新用户创建等)
|
||||||
|
return handleUserMatchAndRegister(dto.getOpenid(), dto.getUnionid(), dto.getPhone(), userType,dto.getOrgType());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("小程序登录异常:" + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return AjaxResult.error("登录失败,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小程序登录主逻辑
|
* 小程序登录主逻辑
|
||||||
* 核心逻辑:优先处理网格员(is_company_user=2),再处理普通招聘者/求职者
|
* 核心逻辑:优先处理网格员(is_company_user=2),再处理普通招聘者/求职者
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class SysJobServiceImpl implements ISysJobService
|
|||||||
public void init() throws SchedulerException, TaskException
|
public void init() throws SchedulerException, TaskException
|
||||||
{
|
{
|
||||||
try (DistributedLockUtil.AutoReleaseLock autoLock =
|
try (DistributedLockUtil.AutoReleaseLock autoLock =
|
||||||
distributedLockUtil.tryLockJob(JOB_INIT_LOCK_KEY, LOCK_ACQUIRE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
|
distributedLockUtil.tryLock(JOB_INIT_LOCK_KEY, LOCK_ACQUIRE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
|
||||||
if (autoLock == null || !autoLock.isLocked()) {
|
if (autoLock == null || !autoLock.isLocked()) {
|
||||||
System.out.println("【定时任务初始化】其他实例已持有锁,当前实例跳过初始化");
|
System.out.println("【定时任务初始化】其他实例已持有锁,当前实例跳过初始化");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
select info_id, user_name, ipaddr, login_location, browser, os, status, msg, login_time,login_time_cipher,user_name_cipher from sys_logininfor
|
select info_id, user_name, ipaddr, login_location, browser, os, status, msg, login_time,login_time_cipher,user_name_cipher from sys_logininfor
|
||||||
<where>
|
<where>
|
||||||
<if test="ipaddr != null and ipaddr != ''">
|
<if test="ipaddr != null and ipaddr != ''">
|
||||||
AND ipaddr like concat('%', #{ipaddr}, '%')
|
AND ipaddr like concat('%', CAST(#{ipaddr} AS VARCHAR), '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="status != null and status != ''">
|
<if test="status != null and status != ''">
|
||||||
AND status = #{status}
|
AND status = #{status}
|
||||||
</if>
|
</if>
|
||||||
<if test="userName != null and userName != ''">
|
<if test="userName != null and userName != ''">
|
||||||
AND user_name like concat('%', #{userName}, '%')
|
AND user_name like concat('%', CAST(#{userName} AS VARCHAR), '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
AND login_time >= #{params.beginTime}
|
AND login_time >= #{params.beginTime}
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<include refid="selectOperLogVo"/>
|
<include refid="selectOperLogVo"/>
|
||||||
<where>
|
<where>
|
||||||
<if test="operIp != null and operIp != ''">
|
<if test="operIp != null and operIp != ''">
|
||||||
AND oper_ip like concat('%', #{operIp}, '%')
|
AND oper_ip like concat('%', CAST(#{operIp} AS VARCHAR), '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="title != null and title != ''">
|
<if test="title != null and title != ''">
|
||||||
AND title like concat('%', #{title}, '%')
|
AND title like concat('%', CAST(#{title} AS VARCHAR), '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="businessType != null">
|
<if test="businessType != null">
|
||||||
AND business_type = #{businessType}
|
AND business_type = #{businessType}
|
||||||
@@ -58,7 +58,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
AND status = #{status}
|
AND status = #{status}
|
||||||
</if>
|
</if>
|
||||||
<if test="operName != null and operName != ''">
|
<if test="operName != null and operName != ''">
|
||||||
AND oper_name like concat('%', #{operName}, '%')
|
AND oper_name like concat('%', CAST(#{operName} AS VARCHAR), '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||||
AND oper_time >= #{params.beginTime}
|
AND oper_time >= #{params.beginTime}
|
||||||
|
|||||||
Reference in New Issue
Block a user