Commit f9644a69 by kenzo
parents 698a3421 a31b5b87
...@@ -71,7 +71,7 @@ public class SlideCaptchaService { ...@@ -71,7 +71,7 @@ public class SlideCaptchaService {
/** /**
* 在背景图上绘制滑块挖空效果 * 在背景图上绘制滑块挖空效果
*/ */
private void drawSliderHole(BufferedImage background, int x, int y) { private void drawSliderHoleOld(BufferedImage background, int x, int y) {
Graphics2D g2d = background.createGraphics(); Graphics2D g2d = background.createGraphics();
// 设置挖空区域 // 设置挖空区域
...@@ -87,9 +87,22 @@ public class SlideCaptchaService { ...@@ -87,9 +87,22 @@ public class SlideCaptchaService {
g2d.dispose(); g2d.dispose();
} }
/** /**
* 在背景图上绘制滑块挖空效果
*/
private void drawSliderHole(BufferedImage background, int x, int y) {
Graphics2D g2d = background.createGraphics();
// 设置挖空区域
// 创建半透明效果,能看到下层背景
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); // 50%透明度
// 使用灰色填充
g2d.setColor(new Color(100, 100, 100)); // 深灰色
g2d.fillRect(x, y, SLIDER_WIDTH, SLIDER_HEIGHT);
g2d.dispose();
}
/**
* 创建带阴影效果的滑块 * 创建带阴影效果的滑块
*/ */
private BufferedImage createSliderWithShadow(BufferedImage background, int x, int y) { private BufferedImage createSliderWithShadowOld(BufferedImage background, int x, int y) {
int width = 50; int width = 50;
int height = 50; int height = 50;
int shadowSize = 3; int shadowSize = 3;
...@@ -123,6 +136,23 @@ public class SlideCaptchaService { ...@@ -123,6 +136,23 @@ public class SlideCaptchaService {
} }
/** /**
* 创建带阴影效果的滑块
*/
private BufferedImage createSliderWithShadow(BufferedImage background, int x, int y) {
int width = 50;
int height = 50;
BufferedImage slider = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = slider.createGraphics();
// 直接截取背景图部分,不需要复杂的效果
BufferedImage subImage = background.getSubimage(x, y, width, height);
g2d.drawImage(subImage, 0, 0, null);
g2d.dispose();
return slider;
}
/**
* 调整图片尺寸 * 调整图片尺寸
*/ */
private BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) { private BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
......
...@@ -17,12 +17,12 @@ public interface SmsService { ...@@ -17,12 +17,12 @@ public interface SmsService {
* @param phone 手机号 * @param phone 手机号
* @return 是否发送成功 * @return 是否发送成功
*/ */
boolean sendSmsCode(String phone); boolean sendSmsCode(String phone,int smsTemplateType);
boolean sendMasSmsCode(String phone); boolean sendGlySmsCode(String phone,int smsTemplateType);
boolean sendMasSmsContent(String phone, String content); boolean sendGlySmsContent(String phone, String content, String code, int smsTemplateType);
void asyncSendMasSmsContent(String phone, String content); void asyncSendGlySmsContent(String phone, String content, String code, int smsTemplateType);
} }
...@@ -102,7 +102,7 @@ public class LoginServiceImpl implements LoginService { ...@@ -102,7 +102,7 @@ public class LoginServiceImpl implements LoginService {
if(!flag){ if(!flag){
throw new BusinessException(GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getCode(),GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getMsg()); throw new BusinessException(GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getCode(),GlobalErrorCodeConstants.CAPTCHA_EXPIRED.getMsg());
}else{*/ }else{*/
boolean smsfalg = smsService.sendSmsCode(vo.getPhoneNumber()); boolean smsfalg = smsService.sendSmsCode(vo.getPhoneNumber(),vo.getSmsTemplateType());
if(!smsfalg) { if(!smsfalg) {
throw new BusinessException(GlobalErrorCodeConstants.SEND_SMS_ERROR.getCode(),GlobalErrorCodeConstants.SEND_SMS_ERROR.getMsg()); throw new BusinessException(GlobalErrorCodeConstants.SEND_SMS_ERROR.getCode(),GlobalErrorCodeConstants.SEND_SMS_ERROR.getMsg());
} else { } else {
......
...@@ -2,6 +2,7 @@ package com.cnooc.expert.auth.service.impl; ...@@ -2,6 +2,7 @@ package com.cnooc.expert.auth.service.impl;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import com.cnooc.expert.common.constant.TokenConstants; import com.cnooc.expert.common.constant.TokenConstants;
import com.cnooc.expert.common.utils.JsonUtils;
import com.cnooc.expert.common.utils.SmsHttpUtil; import com.cnooc.expert.common.utils.SmsHttpUtil;
import com.cnooc.expert.common.utils.SmsUtil; import com.cnooc.expert.common.utils.SmsUtil;
import com.cnooc.expert.system.entity.vo.SmsConfig; import com.cnooc.expert.system.entity.vo.SmsConfig;
...@@ -20,7 +21,9 @@ import java.util.concurrent.CompletableFuture; ...@@ -20,7 +21,9 @@ import java.util.concurrent.CompletableFuture;
@AllArgsConstructor @AllArgsConstructor
@Slf4j @Slf4j
public class SmsServiceImpl implements SmsService { public class SmsServiceImpl implements SmsService {
public static final String SMS_CODE_CONTENT = "福建通信行业融合创新服务平台,您的验证码是:%s(有效期为2分钟),请勿泄露给他人,如非本人操作,请忽略此消息。"; // public static final String SMS_CODE_CONTENT = "您的验证码是:%s(有效期为2分钟),请勿泄露给他人,如非本人操作,请忽略此消息。";
public static final String SMS_LOGIN_CODE_CONTENT = "【专家小程序】您正在登录专家小程序,请确认是本人操作。验证码为:%s,10分钟内有效,请勿告知他人。‌";
public static final String SMS_CHANGEPWD_CODE_CONTENT = "【专家小程序】您正在修改登录密码,请确认是本人操作。验证码为:%s,10分钟内有效,请勿告知他人。";
@Autowired @Autowired
private StringRedisTemplate redisTemplate; private StringRedisTemplate redisTemplate;
private final SmsConfig smsConfig; private final SmsConfig smsConfig;
...@@ -50,20 +53,20 @@ public class SmsServiceImpl implements SmsService { ...@@ -50,20 +53,20 @@ public class SmsServiceImpl implements SmsService {
* @param phone 手机号 * @param phone 手机号
* @return 是否发送成功 * @return 是否发送成功
*/ */
public boolean sendSmsCode(String phone) { public boolean sendSmsCode(String phone,int smsTemplateType) {
// 生成6位验证码 // 生成6位验证码
//String code = RandomUtil.randomNumbers(6); //String code = RandomUtil.randomNumbers(6);
String code = "666666"; String code = "666666";
String key = "sms:code:" + phone; String key = "sms:code:" + phone;
redisTemplate.opsForValue().set(key, code, 5,TimeUnit.MINUTES);// 存入 Redis,设置过期时间为5分钟 redisTemplate.opsForValue().set(key, code, 10,TimeUnit.MINUTES);// 存入 Redis,设置过期时间为10分钟
//String storedCode = (String)redisTemplate.opsForValue().get(key); //String storedCode = (String)redisTemplate.opsForValue().get(key);
System.out.println("发送短信验证码:" + phone + " -> " + code);// 模拟发送短信,实际应调用第三方短信服务 System.out.println("发送短信验证码:" + phone + " -> " + code);// 模拟发送短信,实际应调用第三方短信服务
return true; return true;
//return sendMasSmsCode(phone); //return sendGlySmsCode(phone,smsTemplateType);
} }
@Override @Override
public boolean sendMasSmsCode(String phone) { public boolean sendGlySmsCode(String phone,int smsTemplateType) {
// 生成验证码并构建缓存键 // 生成验证码并构建缓存键
String code = SmsUtil.generateVerificationCode(); String code = SmsUtil.generateVerificationCode();
System.out.println("发送短信验证码:" + phone + " -> " + code); System.out.println("发送短信验证码:" + phone + " -> " + code);
...@@ -71,14 +74,18 @@ public class SmsServiceImpl implements SmsService { ...@@ -71,14 +74,18 @@ public class SmsServiceImpl implements SmsService {
try { try {
// 构建短信内容 // 构建短信内容
String content = String.format(SMS_CODE_CONTENT, code); String content = String.format(SMS_LOGIN_CODE_CONTENT, code);
if(smsTemplateType == 2){
//修改密码
content = String.format(SMS_CHANGEPWD_CODE_CONTENT, code);
}
System.out.println("发送短信验证码:" + phone + " -> " + code); System.out.println("发送短信验证码:" + phone + " -> " + code);
log.info("云MAS业务平台 发送手机号: {},短信验证码:{}", phone, code); log.info("云MAS业务平台 发送手机号: {},短信验证码:{}", phone, code);
System.out.println("云MAS业务平台 短信内容: " + content); System.out.println("云MAS业务平台 短信内容: " + content);
boolean result = sendMasSmsContent(phone, content); boolean result = sendGlySmsContent(phone, content, code, smsTemplateType);
if(result){ if(result){
redisTemplate.opsForValue().set(key, code, 2 * 60); // 存入 Redis,设置过期时间为2分钟 redisTemplate.opsForValue().set(key, code, 10 * 60); // 存入 Redis,设置过期时间为10分钟
} }
return result; return result;
} catch (Exception e) { } catch (Exception e) {
...@@ -89,42 +96,37 @@ public class SmsServiceImpl implements SmsService { ...@@ -89,42 +96,37 @@ public class SmsServiceImpl implements SmsService {
} }
@Override @Override
public boolean sendMasSmsContent(String phone, String content) { public boolean sendGlySmsContent(String phone, String content, String code, int smsTemplateType) {
try { try {
log.info("云MAS业务平台 短信内容: {}", content); log.info("管理云业务平台 短信内容: {}", content);
log.info("云MAS业务平台 发送手机号: {},短信内容:{}", phone, content); log.info("管理云业务平台 发送手机号: {},短信内容:{}", phone, content);
// 生成 MAC 签名
String mac = SmsUtil.calculateMac(smsConfig.getEcName(), smsConfig.getApId(), smsConfig.getSecretKey(),
phone, content, smsConfig.getSign(), smsConfig.getAddSerial());
System.out.println("云MAS业务平台 mac签名: " + mac);
log.info("云MAS业务平台 mac签名: {}", mac);
// 构建请求体并转换为 Base64 编码的 JSON 字符串 // 构建请求体并转换为 Base64 编码的 JSON 字符串
String encodedJson = SmsUtil.encodeRequestBodyToBase64(buildRequestBody(phone, content, mac)); String encodedJson = SmsUtil.encodeRequestBodyToBase64(buildRequestBody(phone, content, code,smsTemplateType));
System.out.println("云MAS业务平台 请求体Base64编码: " + encodedJson); System.out.println("管理云业务平台 请求体Base64编码: " + encodedJson);
log.info("云MAS业务平台 请求体Base64编码: {}", encodedJson); log.info("管理云业务平台 请求体Base64编码: {}", encodedJson);
// 设置请求头并发送 POST 请求 // 设置请求头并发送 POST 请求
String response = SmsHttpUtil.sendPostRequest(smsConfig.getApiUrl(), encodedJson); String response = SmsHttpUtil.sendPostRequest(smsConfig.getApiUrl(), encodedJson,smsConfig.getAppCode());
System.out.println("云MAS业务平台 响应体: " + response); System.out.println("管理云业务平台 响应体: " + response);
log.info("云MAS业务平台 响应体response: {}", response); log.info("管理云业务平台 响应体response: {}", response);
// 解析响应并处理结果 // 解析响应并处理结果
return SmsUtil.handleResponse(response); return SmsUtil.handleResponse(response);
} catch (Exception e) { } catch (Exception e) {
log.error("云MAS业务平台短信发送失败: {}", e.getMessage(), e); log.error("管理云业务平台短信发送失败: {}", e.getMessage(), e);
return false; return false;
} }
} }
@Override @Override
public void asyncSendMasSmsContent(String phone, String content){ public void asyncSendGlySmsContent(String phone, String content, String code, int smsTemplateType){
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() -> {
try { try {
System.out.println("======开始发送短信======"); System.out.println("======开始发送短信======");
sendMasSmsContent(phone, content); sendGlySmsContent(phone, content,code,smsTemplateType);
System.out.println("======发送短信结束======"); System.out.println("======发送短信结束======");
} catch (Exception e) { } catch (Exception e) {
log.error("asyncSendMasSmsContent异步执行失败", e); log.error("asyncSendMasSmsContent异步执行失败", e);
...@@ -136,16 +138,26 @@ public class SmsServiceImpl implements SmsService { ...@@ -136,16 +138,26 @@ public class SmsServiceImpl implements SmsService {
/** /**
* 构建请求体 * 构建请求体
*/ */
private Map<String, String> buildRequestBody(String phone, String content, String mac) { private Map<String, String> buildRequestBody(String phone, String content, String code, int smsTemplateType) {
Map<String, Object> sms = new HashMap<>();
Map<String, String> dataItems = new HashMap<>();
dataItems.put("code", code);
dataItems.put("time", "10");
sms.put("template", smsConfig.getLoginTemplate());
if(smsTemplateType == 2){
sms.put("template", smsConfig.getChangePwdTemplate());
}
sms.put("dataItems", JsonUtils.toJsonString((dataItems)));
sms.put("type", "1");
String[] recvNumArray = new String[1];
recvNumArray[0] = phone;
sms.put("recvNum", recvNumArray);
//sms.put("content", content);
sms.put("sendNum", "");
Map<String, String> requestBody = new HashMap<>(); Map<String, String> requestBody = new HashMap<>();
requestBody.put("ecName", smsConfig.getEcName()); requestBody.put("priority", "high");
requestBody.put("apId", smsConfig.getApId()); requestBody.put("label", "消息标签");
requestBody.put("mobiles", phone); requestBody.put("sms", JsonUtils.toJsonString(sms));
requestBody.put("content", content);
requestBody.put("secretKey", smsConfig.getSecretKey());
requestBody.put("sign", smsConfig.getSign());
requestBody.put("addSerial", smsConfig.getAddSerial());
requestBody.put("mac", mac);
return requestBody; return requestBody;
} }
......
...@@ -16,11 +16,12 @@ public class SmsHttpUtil { ...@@ -16,11 +16,12 @@ public class SmsHttpUtil {
* @param requestBody 请求体 Map * @param requestBody 请求体 Map
* @return 响应字符串 * @return 响应字符串
*/ */
public static String sendPostRequest(String apiUrl, String requestBody) { public static String sendPostRequest(String apiUrl, String requestBody,String appCode) {
try { try {
// 设置请求头 // 设置请求头
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization","APPCODE "+appCode);
// 构建请求实体 // 构建请求实体
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers); HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers);
......
...@@ -178,17 +178,16 @@ public class LoginController { ...@@ -178,17 +178,16 @@ public class LoginController {
* 验证图片验证码 * 验证图片验证码
*/ */
@PostMapping("/verifyCaptcha") @PostMapping("/verifyCaptcha")
public ResponseEntity<Map<String, Object>> verifyCaptchaNew( public ApiResult<Map<String, Object>> verifyCaptchaNew(
@RequestParam String captchaId, @RequestBody VerifyRequest request) {
@RequestParam String inputCode) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
boolean flag = sysCaptchaService.validate(captchaId, inputCode); boolean flag = sysCaptchaService.validate(request.getCaptchaId(), request.getInputCode());
String msg = "验证成功"; String msg = "验证成功";
if (!flag) { if (!flag) {
msg = "验证失败"; msg = "验证失败";
} }
result.put("success", flag); result.put("success", flag);
result.put("message", msg); result.put("message", msg);
return ResponseEntity.ok(result); return ApiResult.successWithResult(result);
} }
} }
...@@ -5,4 +5,6 @@ import lombok.Data; ...@@ -5,4 +5,6 @@ import lombok.Data;
public class VerifyRequest { public class VerifyRequest {
private String token; private String token;
private Integer moveX; // 滑块移动的X距离 private Integer moveX; // 滑块移动的X距离
private String captchaId;
private String inputCode;
} }
...@@ -28,6 +28,10 @@ public class LoginVO { ...@@ -28,6 +28,10 @@ public class LoginVO {
@Min(value = 1) @Min(value = 1)
private Integer loginType; private Integer loginType;
@Max(value = 2, message = "短信模版类型只能是1,登录时候发送验证码的短信模版 2.修改密码时候发送验证码的短信模版")
@Min(value = 1)
private Integer smsTemplateType;
//图形验证码的key //图形验证码的key
private String key; private String key;
......
...@@ -11,10 +11,8 @@ import org.springframework.stereotype.Component; ...@@ -11,10 +11,8 @@ import org.springframework.stereotype.Component;
public class SmsConfig { public class SmsConfig {
private String apiUrl; private String apiUrl;
private String ecName; private String appCode;
private String apId; private String loginTemplate;
private String secretKey; private String changePwdTemplate;
private String sign;
private String addSerial;
} }
...@@ -39,7 +39,13 @@ spring: ...@@ -39,7 +39,13 @@ spring:
batch-size: 16384 batch-size: 16384
linger-ms: 1 linger-ms: 1
buffer-memory: 33554432 buffer-memory: 33554432
sms:
config:
# 短信发送配置
api_url: https://gly.api.mcmptest.cnooc/msg/mcmp-msg-api/message
app_code: 3F2504E04F8911D39A0C0305E82C3301
loginTemplate: 登录验证码模版名称
changePwdTemplate: 修改密码验证码模版名称
app: app:
info: info:
appId: 10000 appId: 10000
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment