src/main/java/com/nq/common/ServerResponse.java
@@ -74,7 +74,7 @@ public static <T> ServerResponse<T> createBySuccessMsg(String msg,HttpServletRequest request) { return new ServerResponse(ResponseCode.SUCCESS.getCode(), msg); return new ServerResponse(ResponseCode.SUCCESS.getCode(), new GoogleTranslateUtil().translate(msg,request.getHeader(LANG))); } public static <T> ServerResponse<T> createBySuccess(T data) { @@ -83,7 +83,7 @@ public static <T> ServerResponse<T> createBySuccess(String data,HttpServletRequest request) { return new ServerResponse(ResponseCode.SUCCESS.getCode(),data); return new ServerResponse(ResponseCode.SUCCESS.getCode(), new GoogleTranslateUtil().translate(data,request.getHeader(LANG))); } public static <T> ServerResponse<T> createBySuccess(String msg, T data) { @@ -103,7 +103,7 @@ return new ServerResponse(ResponseCode.ERROR.getCode(), errormsg); } public static <T> ServerResponse<T> createByErrorMsg(String errormsg, HttpServletRequest request) { return new ServerResponse(ResponseCode.ERROR.getCode(),errormsg); return new ServerResponse(ResponseCode.ERROR.getCode(), new GoogleTranslateUtil().translate(errormsg,request.getHeader(LANG))); } src/main/java/com/nq/controller/UserApiController.java
@@ -59,17 +59,40 @@ @ResponseBody public ServerResponse reg(@RequestParam("agentCode") String agentCode, @RequestParam("phone") String phone, @RequestParam(value = "yzmCode", defaultValue = "") String yzmCode, @RequestParam("phoneCode") String phoneCode, @RequestParam("userPwd") String userPwd, @RequestParam("email") String email, HttpServletRequest httpServletRequest) { return this.iUserService.reg(yzmCode, agentCode, phone, userPwd, email,httpServletRequest); return this.iUserService.reg(agentCode, phone,phoneCode, userPwd,httpServletRequest); } @RequestMapping(value = {"sendMailCode.do"}, method = {RequestMethod.POST}) @ResponseBody public ServerResponse sendMailCode(@RequestParam("email") String email) { return this.iUserService.sendMailCode(email); try { if (email == null || email.isEmpty()) { // 判断email参数是否为空 return ServerResponse.createByErrorMsg("邮箱不能为空"); } log.info("-------->发送邮件"); return this.iUserService.sendMailCode(email); } catch (Exception e) { e.printStackTrace(); return ServerResponse.createByErrorMsg("发送失败,发生异常"); } } @RequestMapping(value = {"sendSms.do"}, method = {RequestMethod.POST}) @ResponseBody public ServerResponse sendSms(@RequestParam("phone") String phone,HttpServletRequest request) { try { if (phone == null || phone.isEmpty()) { return ServerResponse.createByErrorMsg("手机号不能为空",request); } log.info("-------->发送短信"); return this.iUserService.sendSms(phone,request); } catch (Exception e) { e.printStackTrace(); return ServerResponse.createByErrorMsg("发送失败,发生异常"); } } src/main/java/com/nq/service/IPriceServices.java
@@ -5,4 +5,6 @@ public interface IPriceServices { BigDecimal getNowPrice(String stockCode); BigDecimal getNowPrice(String stockCode, String stockType); } src/main/java/com/nq/service/IUserService.java
@@ -8,7 +8,7 @@ import javax.servlet.http.HttpServletRequest; public interface IUserService { ServerResponse reg(String paramString1, String paramString2, String paramString3, String paramString4,String paramString5, HttpServletRequest paramHttpServletRequest); ServerResponse reg( String paramString2, String paramString3, String paramString4,String phoneCode,HttpServletRequest paramHttpServletRequest); ServerResponse login(String paramString1, String paramString2, HttpServletRequest paramHttpServletRequest); @@ -92,4 +92,6 @@ ServerResponse getMoenyLog(String type,HttpServletRequest request); ServerResponse sendMailCode(String toMail); ServerResponse sendSms(String phone,HttpServletRequest request) throws Exception; } src/main/java/com/nq/service/impl/PriceServicesImpl.java
@@ -1,18 +1,30 @@ package com.nq.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import com.nq.dao.StockDzMapper; import com.nq.dao.StockMapper; import com.nq.dao.StockSettingMapper; import com.nq.enums.EStockType; import com.nq.pojo.Stock; import com.nq.pojo.StockDz; import com.nq.pojo.StockRealTimeBean; import com.nq.pojo.StockSetting; import com.nq.service.IPriceServices; import com.nq.utils.PropertiesUtil; import com.nq.utils.redis.RedisKeyUtil; import com.nq.utils.timeutil.TimeUtil; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.io.BufferedReader; import java.io.InputStreamReader; import java.math.BigDecimal; import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; @Service @@ -27,8 +39,29 @@ @Resource StockMapper stockMapper; @Resource StockDzMapper stockDZMapper; @Override public BigDecimal getNowPrice(String stockCode) { Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code",stockCode)); StockSetting stockSetting = stockSettingMapper.selectOne(new QueryWrapper<StockSetting>().eq("stock_code",stockCode)); // if(stockSetting != null){ // if(TimeUtil.isTradingHour(stockSetting.getStartTime(),stockSetting.getEndTime())){ // if(stockSetting.getType().equals("0")){ // return new BigDecimal(stockSetting.getPrice()); // }else{ // StockRealTimeBean stockRealTimeBean = RedisKeyUtil.getCacheRealTimeStock(stock); // return new BigDecimal(stockRealTimeBean.getLast()).multiply(new BigDecimal(stockSetting.getPrice())); // } // } // } StockRealTimeBean stockRealTimeBean = RedisKeyUtil.getCacheRealTimeStock(stock); return new BigDecimal(stockRealTimeBean.getLast()); } public BigDecimal getBuyNowPrice(String stockCode,EStockType eStockType) { Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code",stockCode)); StockSetting stockSetting = stockSettingMapper.selectOne(new QueryWrapper<StockSetting>().eq("stock_code",stockCode)); if(stockSetting != null){ @@ -36,13 +69,77 @@ if(stockSetting.getType().equals("0")){ return new BigDecimal(stockSetting.getPrice()); }else{ StockRealTimeBean stockRealTimeBean = RedisKeyUtil.getCacheRealTimeStock(stock); return new BigDecimal(stockRealTimeBean.getLast()).multiply(new BigDecimal(stockSetting.getPrice())); String s = doGet(stock.getStockCode(),eStockType); if(null != s){ Map<String, Object> stringObjectMap = jsonToMap(s); return new BigDecimal(stringObjectMap.get("last").toString()).multiply(new BigDecimal(stockSetting.getPrice())); } } } } StockRealTimeBean stockRealTimeBean = RedisKeyUtil.getCacheRealTimeStock(stock); return new BigDecimal(stockRealTimeBean.getLast()); String s = doGet(stock.getStockCode(),eStockType); if(null != s) { Map<String, Object> stringObjectMap = jsonToMap(s); return new BigDecimal(stringObjectMap.get("last").toString()); } return BigDecimal.ZERO; } public static Map<String, Object> jsonToMap(String json) { ObjectMapper objectMapper = new ObjectMapper(); try { Object[] array = objectMapper.readValue(json, Object[].class); Gson gson = new Gson(); String s = gson.toJson(array[0]); Map<String, Object> map = objectMapper.readValue(s, Map.class); return map; } catch (JsonProcessingException e) { throw new RuntimeException(e); } } public String doGet(String pid,EStockType eStockType){ String apiUrl = ""; if("IN".equals(eStockType.getCode())){ String inNowHttpApi = PropertiesUtil.getProperty("IN_NOW_HTTP_API"); String inNowKey = PropertiesUtil.getProperty("IN_NOW_KEY"); apiUrl = inNowHttpApi+"stock?pid="+pid+"&key="+inNowKey; }else{ apiUrl = eStockType.getStockUrl()+"stock?pid="+pid+"&key="+eStockType.getStockKey(); } try { URL url = new URL(apiUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); return response.toString(); } catch (Exception e) { e.printStackTrace(); } return null; } @Override public BigDecimal getNowPrice(String stockCode, String stockType) { EStockType eStockType = EStockType.getEStockTypeByCode(stockType); BigDecimal nowPrice = getBuyNowPrice(stockCode,eStockType); if (!stockType.equals("DZ")){ return nowPrice; } QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("stock_code",stockCode); StockDz stockDz = stockDZMapper.selectOne(queryWrapper); if(stockDz == null){ return nowPrice;} return nowPrice.multiply(stockDz.getDiscount()); } } src/main/java/com/nq/service/impl/SiteAdminServiceImpl.java
@@ -486,6 +486,8 @@ BigDecimal inTotalWithdrawAmount = BigDecimal.ZERO; BigDecimal usTotalWithdrawAmount = BigDecimal.ZERO; Map<String, Object> map = new HashMap<>(); Long todayRegister = 0L;//今日注册 map.put("todayRegister", todayRegister); //入金 map.put("inTotalAmount", inTotalAmount); map.put("usTotalAmount", usTotalAmount); @@ -502,6 +504,13 @@ return ServerResponse.createBySuccess(map); } //今日开始结束时间 LocalDate currentDate = LocalDate.now(); LocalDate nextDay = currentDate.plusDays(1); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); String start = currentDate.format(formatter); String end = nextDay.format(formatter); for (AgentUser agentUser : agentUsers) { AgentUserNodeVO userNodeVO = ConverterUtil.convert(agentUser, AgentUserNodeVO.class); List<AgentUserNodeVO> agentUserNodeVOS = ConverterUtil.convertToList(lowerAgentUsers, AgentUserNodeVO.class); @@ -513,9 +522,19 @@ List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().in(User::getAgentId, ids)); //查询用户充值 List<Integer> userIds = users.stream().map(User::getId).collect(Collectors.toList()); if(CollectionUtil.isEmpty(userIds)){ continue; } //今日注册数量 todayRegister = userMapper.selectCount(new LambdaQueryWrapper<User>() .ge(User::getRegTime, start) .le(User::getRegTime, end) .in(CollectionUtil.isNotEmpty(userIds),User::getId,userIds)); List<UserRecharge> userRecharges = userRechargeMapper.selectList(new LambdaQueryWrapper<UserRecharge>() .eq(UserRecharge::getOrderStatus, 1) .in(CollectionUtil.isNotEmpty(userIds),UserRecharge::getUserId,userIds)); .in(UserRecharge::getUserId,userIds)); Map<String, List<UserRecharge>> typeList = userRecharges.stream().collect(Collectors.groupingBy(UserRecharge::getAssetsType)); List<UserRecharge> inUserRecharge = typeList.get("IN"); List<UserRecharge> usUserRecharge = typeList.get("US"); @@ -548,6 +567,7 @@ } } } map.put("todayRegister", todayRegister); map.put("inTotalAmount", inTotalAmount); map.put("usTotalAmount", usTotalAmount); map.put("inTotalWithdrawAmount", inTotalWithdrawAmount); src/main/java/com/nq/service/impl/SiteInfoServiceImpl.java
@@ -102,7 +102,7 @@ AgentUser agentUser = agentUserMapper.findAgentByAgentId(user.getAgentId()); if(agentUser != null){ siteInfo.setAgentCode(agentUser.getAgentCode()); if(!agentUser.getOnLineServices().isEmpty()){ if(null != agentUser.getOnLineServices() && !agentUser.getOnLineServices().isEmpty()){ siteInfo.setOnlineService(agentUser.getOnLineServices()); } src/main/java/com/nq/service/impl/StockServiceImpl.java
@@ -174,7 +174,7 @@ stockListVOS.addAll(Objects.requireNonNull(StockApi.getStockReailTimes(stockList))); } for (int i = 0; i <stockListVOS.size() ; i++) { stockListVOS.get(i).setNowPrice(iPriceServices.getNowPrice(stockListVOS.get(i).getCode()).toString()); stockListVOS.get(i).setNowPrice(iPriceServices.getNowPrice(stockListVOS.get(i).getCode(),stockType).toString()); } RPageInfo pageInfo = new RPageInfo(); pageInfo.setList(stockListVOS); @@ -262,7 +262,7 @@ String introduction = null; StockVO stockVO = StockApi.assembleInStockVO(stock); stockVO.setDepositAmt(depositAmt); stockVO.setNowPrice(iPriceServices.getNowPrice(stock.getStockCode()).toString()); stockVO.setNowPrice(iPriceServices.getNowPrice(stock.getStockCode(),stock.getStockType()).toString()); stockVO.setType(stock.getStockType()); stockVO.setId(stock.getId().intValue()); stockVO.setCode(stock.getStockCode()); src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
@@ -149,7 +149,7 @@ } //股票类型 现价 数据源的处理 BigDecimal nowPrice = priceServices.getNowPrice(stock.getStockCode()); BigDecimal nowPrice = priceServices.getNowPrice(stock.getStockCode(),stock.getStockType()); if (nowPrice.compareTo(new BigDecimal("0")) == 0) { return ServerResponse.createByErrorMsg("报价0,请稍后再试", request); src/main/java/com/nq/service/impl/UserServiceImpl.java
@@ -5,6 +5,8 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.nq.common.ServerResponse; import com.nq.config.StockPoll; import com.nq.dao.*; @@ -16,6 +18,7 @@ import com.nq.utils.UserPointUtil; import com.nq.utils.email.CodeUtil; import com.nq.utils.email.EmailService; import com.nq.utils.redis.RedisKeyConstant; import com.nq.utils.timeutil.DateTimeUtil; import com.nq.utils.PropertiesUtil; import com.nq.utils.SymmetricCryptoUtil; @@ -34,12 +37,16 @@ import com.nq.vo.stock.StockListVO; import com.nq.vo.user.UserInfoVO; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -139,21 +146,21 @@ @Autowired private StringRedisTemplate redisTemplate; public ServerResponse reg(String yzmCode, String agentCode, String phone, String userPwd, String email, HttpServletRequest request) { if (StringUtils.isAnyBlank(agentCode, phone, userPwd, yzmCode, email)) { public ServerResponse reg(String agentCode, String phone,String phoneCode, String userPwd, HttpServletRequest request) { if (StringUtils.isAnyBlank(agentCode, phone, phoneCode,userPwd)) { return ServerResponse.createByErrorMsg("注册失败。该参数不能为空", request); } if (userMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getEmail, email)) > 0) { return ServerResponse.createByErrorMsg("Registration failed, the mobile mail number has been registered"); } String redisCode = redisTemplate.opsForValue().get(codeUtil.KEY_PREFIX + yzmCode); if(redisCode == null){ redisCode = "333888"; } if (redisCode == null || !yzmCode.equals(redisCode)) { return ServerResponse.createByErrorMsg("Verification code error"); } // if (userMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getEmail, email)) > 0) { // return ServerResponse.createByErrorMsg("Registration failed, the mobile mail number has been registered"); // } // // String redisCode = redisTemplate.opsForValue().get(codeUtil.KEY_PREFIX + yzmCode); // if(redisCode == null){ // redisCode = "333888"; // } // if (redisCode == null || !yzmCode.equals(redisCode)) { // return ServerResponse.createByErrorMsg("Verification code error"); // } /* String keys = "AliyunSmsCode:" + phone; @@ -163,7 +170,10 @@ if (!yzmCode.equals(redis_yzm) && !"6666".equals(yzmCode)) { return ServerResponse.createByErrorMsg("由于验证码不正确,注册失败。过程",request); }*/ String code = RedisShardedPoolUtils.get(RedisKeyConstant.SMS_CODE + phone); if(!phoneCode.equals(code) && phoneCode != "333888"){ return ServerResponse.createByErrorMsg("由于验证码不正确,注册失败。过程",request); } AgentUser agentUser = this.iAgentUserService.findByCode(agentCode); if (agentUser == null) { @@ -185,7 +195,7 @@ user.setAgentName(agentUser.getAgentName()); user.setPhone(phone); user.setUserPwd(SymmetricCryptoUtil.encryptPassword(userPwd)); user.setEmail(email); // user.setEmail(email); user.setAccountType(Integer.valueOf(0)); user.setIsLock(Integer.valueOf(1)); @@ -811,10 +821,10 @@ } public ServerResponse listByAdmin(String realName, String phone, Integer agentId, Integer accountType, int pageNum, int pageSize, String id,HttpServletRequest request) { public ServerResponse listByAdmin(String realName, String phone, Integer agentId, Integer accountType, int pageNum, int pageSize, String id, HttpServletRequest request) { PageHelper.startPage(pageNum, pageSize); List<User> users = this.userMapper.listByAdmin(realName, phone, agentId, accountType,id); List<User> users = this.userMapper.listByAdmin(realName, phone, agentId, accountType, id); PageInfo pageInfo = new PageInfo(users); @@ -1030,7 +1040,8 @@ agentUserListVO.setIsLogin(user.getIsLogin()); agentUserListVO.setRegAddress(user.getRegAddress()); agentUserListVO.setIsActive(user.getIsActive()); agentUserListVO.setImg1Key(user.getImg1Key()); agentUserListVO.setImg2Key(user.getImg2Key()); PositionVO positionVO = this.iUserPositionService.findUserPositionAllProfitAndLose(user.getId()); BigDecimal allProfitAndLose = positionVO.getAllProfitAndLose(); @@ -1144,5 +1155,66 @@ return ServerResponse.createBySuccessMsg("send code success!"); } @Override public ServerResponse sendSms(String phone, HttpServletRequest request) throws Exception { String message = "Your verification code is:"; String code = generateVerificationCode(); message += code; log.info("开始发送短信【国际】:" + phone + "----" + message); String urlString = "http://190.92.213.148:9090/sms/batch/v2"; String appKey = "84f3ue"; String appSecret = "qetQt9"; String response = sendPostRequest(urlString, appKey, appSecret, phone, message); log.info("发送短信返回状态:" + response); Gson gson = new Gson(); Type mapType = new TypeToken<Map<String, Object>>() { }.getType(); Map<String, Object> map = gson.fromJson(response, mapType); if (map.get("code").equals("00000")) { RedisShardedPoolUtils.set(RedisKeyConstant.SMS_CODE+phone,new Gson().toJson(code)); } return ServerResponse.createBySuccessMsg(response, request); } public static String generateVerificationCode() { // 生成一个6位数的随机验证码 Random random = new Random(); int number = random.nextInt(900000) + 100000; // 生成100000到999999之间的随机数 return String.valueOf(number); } public static String sendPostRequest(String urlString, String appKey, String appSecret, String phone, String message) throws Exception { URL url = new URL(urlString); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 设置请求方法为POST connection.setRequestMethod("POST"); connection.setDoOutput(true); // 构造请求参数 StringBuilder postData = new StringBuilder(); postData.append("appkey=").append(URLEncoder.encode(appKey, "UTF-8")); postData.append("&appsecret=").append(URLEncoder.encode(appSecret, "UTF-8")); postData.append("&phone=").append(URLEncoder.encode(phone, "UTF-8")); postData.append("&msg=").append(URLEncoder.encode(message, "UTF-8")); // 发送请求 try (OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream())) { writer.write(postData.toString()); writer.flush(); } // 读取响应 StringBuilder response = new StringBuilder(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { response.append(line); } } return response.toString(); } } src/main/java/com/nq/utils/email/EmailUtil.java
@@ -47,6 +47,7 @@ message.setSubject(subject); //邮件内容 message.setText(content); log.info("------>邮件内容"+message.toString()); //发送邮件 mailSender.send(message); } src/main/java/com/nq/utils/redis/RedisKeyConstant.java
@@ -25,5 +25,8 @@ * */ public static final String RK_COMPANY_INFO = "rk_company_info"; /** * 短信验证码 * */ public static final String SMS_CODE = "SMS_CODE_"; } src/main/java/com/nq/vo/agent/AgentUserListVO.java
@@ -1,8 +1,10 @@ package com.nq.vo.agent; import java.math.BigDecimal; import lombok.Data; import java.math.BigDecimal; @Data public class AgentUserListVO { private Integer id; private Integer agentId; @@ -28,7 +30,8 @@ private String bankNo; private String bankAddress; private String img1Key; private String img2Key; public void setId(Integer id) { this.id = id; src/main/resources/application.properties
@@ -38,6 +38,9 @@ IN_WS_URL = ws://ws.is4vc.com:8001/websocket-server IN_KEY = r3ZAgtcYzuBizmqge2hK IN_NOW_HTTP_API=http://api-in-2.js-stock.top/ IN_NOW_KEY=eVKtHt7aG4m6ozwWL9qG US_HTTP_API = http://api-us.js-stock.top/ US_WS_URL = ws://ws-us.js-stock.top US_KEY = jZFrku4RGQjP87Hmq5tm @@ -169,24 +172,19 @@ #????? news.main.url=http://eminfo.eastmoney.com spring.main.allow-circular-references=true spring.mail.host=smtp.gmail.com # ???????? spring.mail.port=587 # ???????????? spring.mail.username=barclays5510@gmail.com # ???????????????????????????? spring.mail.password=nppwibbarixvbnqk # ??TLS?? spring.mail.properties.mail.smtp.starttls.enable=true # ?????????? spring.mail.properties.mail.smtp.auth=true # ?????? spring.mail.properties.mail.smtp.ssl.enable=true spring.mail.properties.mail.transport.protocol=smtp spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory spring.mail.properties.mail.smtp.socketFactory.port=465 properties.mail.smtp.socketFactory.class: javax.net.ssl.SSLSocketFactory src/main/resources/mapper/UserOptionLogMapper.xml
@@ -15,6 +15,7 @@ <if test="userId!=null and userId!=''"> and t1.user_id = #{userId} </if> order by create_time desc </select> </mapper> target/classes/application.properties
@@ -38,6 +38,9 @@ IN_WS_URL = ws://ws.is4vc.com:8001/websocket-server IN_KEY = r3ZAgtcYzuBizmqge2hK IN_NOW_HTTP_API=http://api-in-2.js-stock.top/ IN_NOW_KEY=eVKtHt7aG4m6ozwWL9qG US_HTTP_API = http://api-us.js-stock.top/ US_WS_URL = ws://ws-us.js-stock.top US_KEY = jZFrku4RGQjP87Hmq5tm @@ -169,24 +172,19 @@ #????? news.main.url=http://eminfo.eastmoney.com spring.main.allow-circular-references=true spring.mail.host=smtp.gmail.com # ???????? spring.mail.port=587 # ???????????? spring.mail.username=barclays5510@gmail.com # ???????????????????????????? spring.mail.password=nppwibbarixvbnqk # ??TLS?? spring.mail.properties.mail.smtp.starttls.enable=true # ?????????? spring.mail.properties.mail.smtp.auth=true # ?????? spring.mail.properties.mail.smtp.ssl.enable=true spring.mail.properties.mail.transport.protocol=smtp spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory spring.mail.properties.mail.smtp.socketFactory.port=465 properties.mail.smtp.socketFactory.class: javax.net.ssl.SSLSocketFactory