|
|
@@ -10,6 +10,8 @@ import com.fs.app.utils.WxUtil;
|
|
|
import com.fs.common.VerifyCodeUtil;
|
|
|
import com.fs.common.annotation.Log;
|
|
|
import com.fs.common.annotation.RepeatSubmit;
|
|
|
+import com.fs.common.constant.Constants;
|
|
|
+import com.fs.common.core.domain.AjaxResult;
|
|
|
import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.core.domain.entity.SysDictData;
|
|
|
import com.fs.common.core.page.TableDataInfo;
|
|
|
@@ -20,7 +22,9 @@ import com.fs.common.service.ISmsService;
|
|
|
import com.fs.common.utils.CloudHostUtils;
|
|
|
import com.fs.common.utils.ServletUtils;
|
|
|
import com.fs.common.utils.ip.IpUtils;
|
|
|
+import com.fs.common.utils.sign.Base64;
|
|
|
import com.fs.common.utils.sign.Md5Utils;
|
|
|
+import com.fs.common.utils.uuid.IdUtils;
|
|
|
import com.fs.core.config.WxOpenProperties;
|
|
|
import com.fs.course.domain.FsCoursePlaySourceConfig;
|
|
|
import com.fs.course.domain.LuckyBag;
|
|
|
@@ -34,12 +38,14 @@ import com.fs.his.mapper.FsUserWxMapper;
|
|
|
import com.fs.his.service.IFsUserCouponService;
|
|
|
import com.fs.his.service.IFsUserNewTaskService;
|
|
|
import com.fs.his.service.IFsUserService;
|
|
|
+import com.fs.his.utils.PhoneUtil;
|
|
|
import com.fs.his.vo.FsUserRegisterParam;
|
|
|
import com.fs.im.dto.OpenImResponseDTO;
|
|
|
import com.fs.im.service.OpenIMService;
|
|
|
import com.fs.qw.service.ILuckyBagService;
|
|
|
import com.fs.system.service.ISysDictTypeService;
|
|
|
import com.fs.utils.ContentCheckUtil;
|
|
|
+import com.google.code.kaptcha.Producer;
|
|
|
import io.netty.util.internal.StringUtil;
|
|
|
import io.swagger.annotations.Api;
|
|
|
import io.swagger.annotations.ApiOperation;
|
|
|
@@ -49,10 +55,16 @@ import org.apache.ibatis.annotations.Param;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.FastByteArrayOutputStream;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
|
|
+import javax.annotation.Resource;
|
|
|
+import javax.imageio.ImageIO;
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
+import java.io.IOException;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
@@ -103,6 +115,16 @@ public class AppLoginController extends AppBaseController{
|
|
|
|
|
|
@Autowired
|
|
|
private ISysDictTypeService dictTypeService;
|
|
|
+
|
|
|
+ @Resource(name = "captchaProducer")
|
|
|
+ private Producer captchaProducer;
|
|
|
+
|
|
|
+ @Resource(name = "captchaProducerMath")
|
|
|
+ private Producer captchaProducerMath;
|
|
|
+
|
|
|
+ @Value("${fs.captchaType}")
|
|
|
+ private String captchaType;
|
|
|
+
|
|
|
@ApiOperation("注册app用户")
|
|
|
@PostMapping("/register")
|
|
|
@RepeatSubmit
|
|
|
@@ -1077,6 +1099,130 @@ public class AppLoginController extends AppBaseController{
|
|
|
return R.ok("验证码已发送");
|
|
|
}
|
|
|
|
|
|
+ @ApiOperation("获取App登录图形验证码")
|
|
|
+ @GetMapping("/appLoginCaptchaImage")
|
|
|
+ public AjaxResult getAppLoginCaptchaImage() throws IOException {
|
|
|
+ String uuid = IdUtils.simpleUUID();
|
|
|
+ String verifyKey = Constants.APP_LOGIN_CAPTCHA_CODE_KEY + uuid;
|
|
|
+
|
|
|
+ String capStr;
|
|
|
+ String code;
|
|
|
+ BufferedImage image;
|
|
|
+
|
|
|
+ if ("math".equals(captchaType)) {
|
|
|
+ String capText = captchaProducerMath.createText();
|
|
|
+ capStr = capText.substring(0, capText.lastIndexOf("@"));
|
|
|
+ code = capText.substring(capText.lastIndexOf("@") + 1);
|
|
|
+ image = captchaProducerMath.createImage(capStr);
|
|
|
+ } else {
|
|
|
+ capStr = code = captchaProducer.createText();
|
|
|
+ image = captchaProducer.createImage(capStr);
|
|
|
+ }
|
|
|
+
|
|
|
+ redisCache.setCacheObject(verifyKey, code, Constants.APP_LOGIN_CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
|
|
|
+
|
|
|
+ FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
|
|
+ ImageIO.write(image, "jpg", os);
|
|
|
+
|
|
|
+ AjaxResult ajax = AjaxResult.success();
|
|
|
+ ajax.put("uuid", uuid);
|
|
|
+ ajax.put("img", Base64.encode(os.toByteArray()));
|
|
|
+ return ajax;
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("发送短信验证码(需图形验证码)")
|
|
|
+ @PostMapping("/sendCodeWithCaptcha")
|
|
|
+ public R sendCodeWithCaptcha(@RequestBody Map<String, String> body) {
|
|
|
+ String phone = body.get("phone");
|
|
|
+ String captchaCode = body.get("captchaCode");
|
|
|
+ String captchaUuid = body.get("captchaUuid");
|
|
|
+
|
|
|
+ if (!PhoneUtil.isNormalPhone(phone)) {
|
|
|
+ return R.error("手机号格式不正确");
|
|
|
+ }
|
|
|
+
|
|
|
+ R captchaError = validateAppLoginCaptcha(captchaCode, captchaUuid);
|
|
|
+ if (captchaError != null) {
|
|
|
+ return captchaError;
|
|
|
+ }
|
|
|
+
|
|
|
+ String smsCodeKey = "sms:code:" + phone;
|
|
|
+ String smsCooldownKey = "sms:cooldown:" + phone;
|
|
|
+
|
|
|
+ if (redisCache.getCacheObject(smsCooldownKey) != null) {
|
|
|
+ return R.error("验证码已发送,请稍后再试");
|
|
|
+ }
|
|
|
+
|
|
|
+ String smsCode = VerifyCodeUtil.generateCode();
|
|
|
+ smsService.sendCaptcha(phone, smsCode, "验证码");
|
|
|
+ redisCache.setCacheObject(smsCodeKey, smsCode, 180, TimeUnit.SECONDS);
|
|
|
+ redisCache.setCacheObject(smsCooldownKey, "1", 60, TimeUnit.SECONDS);
|
|
|
+
|
|
|
+ return R.ok("验证码已发送");
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("手机号登录(需图形验证码)")
|
|
|
+ @PostMapping("/loginByPhoneWithCaptcha")
|
|
|
+ public R loginByPhoneWithCaptcha(@RequestBody Map<String, String> map) {
|
|
|
+ String phone = map.get("phone");
|
|
|
+ String code = map.get("code");
|
|
|
+ String captchaCode = map.get("captchaCode");
|
|
|
+ String captchaUuid = map.get("captchaUuid");
|
|
|
+
|
|
|
+ if (!PhoneUtil.isNormalPhone(phone)) {
|
|
|
+ return R.error("手机号格式不正确");
|
|
|
+ }
|
|
|
+
|
|
|
+ R captchaError = validateAppLoginCaptcha(captchaCode, captchaUuid);
|
|
|
+ if (captchaError != null) {
|
|
|
+ return captchaError;
|
|
|
+ }
|
|
|
+
|
|
|
+ String encryptPhone = encryptPhone(phone);
|
|
|
+ List<FsUser> user = userService.selectFsUserListByPhone(encryptPhone);
|
|
|
+ if (CollectionUtil.isEmpty(user)) {
|
|
|
+ user = userService.selectFsUserListByPhone(encryptPhoneOldKey(phone));
|
|
|
+ }
|
|
|
+ if (CollectionUtil.isEmpty(user)) {
|
|
|
+ user = userService.selectFsUserListByPhone(phone);
|
|
|
+ }
|
|
|
+ if (CollectionUtil.isEmpty(user)) {
|
|
|
+ return R.error("此电话号码未绑定用户");
|
|
|
+ }
|
|
|
+ if (user.size() > 1) {
|
|
|
+ user.removeIf(fsUser -> StringUtils.isEmpty(fsUser.getHistoryApp()));
|
|
|
+ }
|
|
|
+
|
|
|
+ String redisCode = redisCache.getCacheObject("sms:code:" + phone);
|
|
|
+ if (StringUtils.isEmpty(redisCode)) {
|
|
|
+ return R.error("验证码已过期,请重新发送");
|
|
|
+ }
|
|
|
+ if (!redisCode.equals(code)) {
|
|
|
+ return R.error("验证码错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ redisCache.deleteObject(Constants.APP_LOGIN_CAPTCHA_CODE_KEY + captchaUuid);
|
|
|
+ updateExistingUserJpushId(user.get(0), map.get("jpushId"));
|
|
|
+ updateLoginDevice(user.get(0).getUserId(), map.get("loginDevice"), map.get("source"));
|
|
|
+
|
|
|
+ return generateTokenAndReturn(user.get(0));
|
|
|
+ }
|
|
|
+
|
|
|
+ private R validateAppLoginCaptcha(String captchaCode, String captchaUuid) {
|
|
|
+ if (StringUtils.isEmpty(captchaUuid) || StringUtils.isEmpty(captchaCode)) {
|
|
|
+ return R.error("请输入图形验证码");
|
|
|
+ }
|
|
|
+ String verifyKey = Constants.APP_LOGIN_CAPTCHA_CODE_KEY + captchaUuid;
|
|
|
+ String captcha = redisCache.getCacheObject(verifyKey);
|
|
|
+ if (captcha == null) {
|
|
|
+ return R.error("图形验证码已过期,请重新获取");
|
|
|
+ }
|
|
|
+ if (!captchaCode.equalsIgnoreCase(captcha)) {
|
|
|
+ return R.error("图形验证码错误");
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
private List<FsUser> findUsersByPhone(String phone) {
|
|
|
// 先根据加密手机号查询用户
|
|
|
String jiami = (encryptPhone(phone));
|