Selaa lähdekoodia

支付模块:串接测试

tangxiangan 2 vuotta sitten
vanhempi
commit
4fb494299c

+ 11 - 2
pdf-office-account/pom.xml

@@ -103,8 +103,17 @@
             </exclusions>
         </dependency>
         <dependency>
-            <groupId>org.springframework.security.oauth</groupId>
-            <artifactId>spring-security-oauth2</artifactId>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.security.oauth.boot</groupId>
+            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
     </dependencies>
 

+ 25 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/config/ResourceServerConfig.java

@@ -0,0 +1,25 @@
+package cn.kdan.cloud.pdf.office.account.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
+
+/**
+ * 资源提供端的配置
+ */
+@Configuration
+@EnableResourceServer //开启资源提供服务的配置  是默认情况下spring security oauth2的http配置会被WebSecurityConfigurerAdapter的配置覆盖
+@Order(3)
+public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
+        http.authorizeRequests().anyRequest().authenticated();
+    }
+
+}

+ 39 - 0
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/config/WebSecurityConfig.java

@@ -0,0 +1,39 @@
+package cn.kdan.cloud.pdf.office.account.config;
+
+
+import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+/**
+ * 是默认情况下spring security的http配置 优于ResourceServerConfigurerAdapter的配置
+ */
+@Configuration
+@EnableWebSecurity
+@EnableAutoConfiguration(exclude = {org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class})
+@Order(1)
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Value("${httpMatchers.request}")
+    private String httpRequestMatchers;
+    @Value("${httpMatchers.web}")
+    private String httpWebMatchers;
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.csrf().disable();
+        http.authorizeRequests().antMatchers(httpRequestMatchers.split(CommonConstant.STRING_SIGN_COMMA)).permitAll();
+        http.requestMatchers().antMatchers(httpRequestMatchers.split(CommonConstant.STRING_SIGN_COMMA));
+    }
+    @Override
+    public void configure(WebSecurity web) {
+        web.ignoring()
+                .antMatchers(httpWebMatchers.split(CommonConstant.STRING_SIGN_COMMA));
+    }
+}

+ 3 - 2
pdf-office-account/src/main/java/cn/kdan/cloud/pdf/office/account/controller/UserController.java

@@ -14,6 +14,7 @@ import cn.kdan.cloud.pdf.office.account.service.UserService;
 
 import com.github.pagehelper.PageInfo;
 import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.security.oauth2.provider.OAuth2Authentication;
 import org.springframework.security.oauth2.provider.OAuth2Authentication;
 import org.springframework.web.bind.annotation.*;
 
@@ -171,8 +172,8 @@ public class UserController {
      */
     @PostMapping("/logOffForUser")
     public ResultMap<Boolean> logOffForUser(@RequestParam String code, Principal principal) {
-        String userId = me(principal);
-        userService.logOffForUser(code,userId);
+//        String userId = me(principal);
+        userService.logOffForUser(code,"userId");
         return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS,Boolean.TRUE);
     }
 

+ 3 - 1
pdf-office-api/pdf-office-api-account/src/main/java/cn/kdan/cloud/pdf/office/api/account/feign/UserApi.java

@@ -4,7 +4,9 @@ import cn.kdan.cloud.pdf.office.api.account.dto.PermissionGiftDTO;
 import cn.kdan.cloud.pdf.office.api.account.dto.PermissionTransferDTO;
 import cn.kdan.cloud.pdf.office.api.account.dto.UpdateUserForPaySuccessDTO;
 import cn.kdan.cloud.pdf.office.api.account.dto.UpdateUserForRefundDTO;
+import cn.kdan.cloud.pdf.office.api.account.feign.hystrix.OauthClientDetailsApiHystrix;
 import cn.kdan.cloud.pdf.office.api.account.feign.hystrix.UserHystrix;
+import cn.kdan.cloud.pdf.office.common.config.FeignConfig;
 import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
 import cn.kdan.cloud.pdf.office.common.dto.UserRegisterDTO;
 import cn.kdan.cloud.pdf.office.common.pojo.ResultMap;
@@ -18,7 +20,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 
 
 @Component
-@FeignClient(value = CommonConstant.ACCOUNT_PROVIDER_NAME + "/user" , fallback = UserHystrix.class)
+@FeignClient(value = CommonConstant.ACCOUNT_PROVIDER_NAME + "/user" , configuration = FeignConfig.class, fallback = UserHystrix.class)
 public interface UserApi {
 
 

+ 31 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/config/FeignConfig.java

@@ -0,0 +1,31 @@
+package cn.kdan.cloud.pdf.office.common.config;
+
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+import org.apache.http.HttpHeaders;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * feign
+ *
+ * @author tangxiangan
+ */
+@Configuration
+public class FeignConfig implements RequestInterceptor {
+
+    @Override
+    public void apply(RequestTemplate requestTemplate) {
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        if(!ObjectUtils.isEmpty(attributes)){
+            HttpServletRequest request = attributes.getRequest();
+            String token = request.getHeader(HttpHeaders.AUTHORIZATION);
+            requestTemplate.header(HttpHeaders.AUTHORIZATION, token);
+        }
+    }
+
+}

+ 79 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/config/RestTemplateConfig.java

@@ -0,0 +1,79 @@
+package cn.kdan.cloud.pdf.office.common.config;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.client.RestTemplate;
+
+import javax.net.ssl.SSLContext;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * RestTemplate配置类
+ */
+@Configuration
+public class RestTemplateConfig {
+
+    @Bean
+    @LoadBalanced
+    public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
+        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
+
+        SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
+                .loadTrustMaterial(null, acceptingTrustStrategy)
+                .build();
+
+        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext,NoopHostnameVerifier.INSTANCE);
+
+        CloseableHttpClient httpClient = HttpClients.custom()
+                .setSSLSocketFactory(csf)
+                .build();
+
+        HttpComponentsClientHttpRequestFactory requestFactory =
+                new HttpComponentsClientHttpRequestFactory();
+
+        requestFactory.setHttpClient(httpClient);
+
+        RestTemplate restTemplate = new RestTemplate(requestFactory);
+        //替换自定义的MappingJackson2HttpMessageConverter
+        List<HttpMessageConverter<?>> httpMessageConverters = new ArrayList<>();
+        restTemplate.getMessageConverters().stream().forEach(httpMessageConverter -> {
+            if(!(httpMessageConverter instanceof MappingJackson2HttpMessageConverter)){
+                httpMessageConverters.add(httpMessageConverter);
+            }
+        });
+        httpMessageConverters.add(getMappingJackson2HttpMessageConverter());
+        restTemplate.setMessageConverters(httpMessageConverters);
+        return restTemplate;
+    }
+
+    @Bean
+    public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
+        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
+        //设置日期格式
+        ObjectMapper objectMapper = new ObjectMapper();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        objectMapper.setDateFormat(sdf);
+        objectMapper.configure(SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS, false);
+        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
+        return mappingJackson2HttpMessageConverter;
+    }
+}

+ 39 - 10
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/enums/EmailCodeTypeEnum.java

@@ -1,28 +1,57 @@
 package cn.kdan.cloud.pdf.office.common.enums;
 
 public enum EmailCodeTypeEnum {
+    /**
+     * 登录
+     */
+    LOGIN("login","邮箱验证码登录","邮箱验证码登录",""),
+    /**
+     * 注册
+     */
+    USER_REGISTER("user_register","注册验证码","注册验证码",""),
+    /**
+     * 用户注销
+     */
+    USER_LOG_OFF("user_log_off","注销验证码","注销验证码","");
 
-    LOGIN("login"),
-    USER_REGISTER("user_register"),
-    USER_LOG_OFF("user_log_off");
 
+    private final String value;
+    private final String action;
 
-    private String value;
+    private final String subject;
 
-    EmailCodeTypeEnum(String value){
-        this.value = value;
+    private final String text;
+
+    public String subject() {
+        return subject;
     }
 
-    public String value() {
-        return value;
+    public String text() {
+        return text;
+    }
+
+    EmailCodeTypeEnum(String value, String action, String subject, String text) {
+        this.value = value;
+        this.action = action;
+        this.subject = subject;
+        this.text = text;
     }
 
     public static EmailCodeTypeEnum getEnumByValue(String value) {
-        for (EmailCodeTypeEnum modeEnum: EmailCodeTypeEnum.values()) {
+        for (EmailCodeTypeEnum modeEnum : EmailCodeTypeEnum.values()) {
             if (modeEnum.value().equals(value)) {
                 return modeEnum;
             }
         }
-        return EmailCodeTypeEnum.LOGIN;
+        return null;
     }
+
+    public String value() {
+        return value;
+    }
+
+    public String action() {
+        return action;
+    }
+
 }

+ 4 - 0
pdf-office-common/src/main/java/cn/kdan/cloud/pdf/office/common/utils/CommonUtils.java

@@ -228,4 +228,8 @@ public class CommonUtils {
 		return stringBuilder.toString();
 	}
 
+	public static String generateVerifyCode() {
+		return String.valueOf(new Random().nextInt(899999) + 100000);
+	}
+
 }

+ 28 - 0
pdf-office-sso/src/main/java/cn/kdan/cloud/pdf/office/sso/constant/AuthConstant.java

@@ -67,4 +67,32 @@ public class AuthConstant {
 
     public static final String EMAIL_REGISTER_ERROR = "Register error!";
 
+
+    public static final String EXCEPTION_MSG_CODE_ACTION_ERROR = "operation action error";
+
+    public static final String EXCEPTION_MSG_CODE_TYPE_ERROR = "operation action error";
+
+    public static final String SUCCESS_MSG_CODE_SEND = "code send success";
+
+    public static final String SUCCESS_MSG_CODE_SEND_MAIL = "mail send success";
+    public static final String EXCEPTION_MSG_CODE_SEND_ERROR = "code send error";
+    public static final String EXCEPTION_MAIL_CODE_SEND_ERROR = "mail send error";
+
+    public static final String VERIFY_CODE_KEY = "pdf_tech_verifyCode_";
+
+    public static final String VERIFY_CODE_TIME_OUT = "pdf_tech_verifyCode_timeout_";
+
+    public static final Long VERIFY_CODE_KEY_EXPIRE_TIME = 15 * 60L;
+
+    /**
+     * 邀请链接过期时间24小时
+     */
+    public static final Long INVITE_VERIFY_CODE_KEY_EXPIRE_TIME = 72 * 60 * 60L;
+
+    public static final Long VERIFY_CODE_KEY_RESEND_TIME = 60L;
+
+    public static final String VERIFY_CODE_SEND_TOO_QUICKLY = "code send too quickly";
+
+
+
 }

+ 27 - 8
pdf-office-sso/src/main/java/cn/kdan/cloud/pdf/office/sso/controller/AuthController.java

@@ -5,6 +5,7 @@ import cn.kdan.cloud.pdf.office.api.email.feign.EmailApi;
 import cn.kdan.cloud.pdf.office.sso.constant.AuthConstant;
 import cn.kdan.cloud.pdf.office.common.enums.EmailCodeTypeEnum;
 import cn.kdan.cloud.pdf.office.common.dto.UserRegisterDTO;
+import cn.kdan.cloud.pdf.office.sso.enums.VerifyTypeEnum;
 import cn.kdan.cloud.pdf.office.sso.service.AuthService;
 import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
 import cn.kdan.cloud.pdf.office.common.exception.BackendRuntimeException;
@@ -18,6 +19,7 @@ import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.validation.constraints.NotBlank;
 import java.security.Principal;
 import java.util.HashMap;
 import java.util.Map;
@@ -76,29 +78,29 @@ public class AuthController {
     /**
      * 邮箱验证码登录
      * @param email 邮箱
-     * @param code 验证码1
+     * @param password 验证码1
      * @param appId appid
      * @param platformType 平台类型 1 官网 2 后台
      * @param request
      * @return
      */
     @GetMapping("/emailLogin")
-    public ResultMap<TokenVO> emailLogin(@RequestParam String email, @RequestParam String code, @RequestParam String appId,
+    public ResultMap<TokenVO> emailLogin(@RequestParam String email, @RequestParam String password, @RequestParam String appId,
                                        @RequestParam String platformType,  @RequestParam String deviceSign,HttpServletRequest request) {
-        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS, authService.emailLogin(email,code,appId,platformType,deviceSign,request));
+        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS, authService.emailLogin(email,password,appId,platformType,deviceSign,request));
     }
 
-    @GetMapping("/emailRegister")
+    @PostMapping("/emailRegister")
     public ResultMap<TokenVO> emailRegister(@RequestBody UserRegisterDTO userRegisterDTO) {
         return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS, authService.emailRegister(userRegisterDTO));
     }
 
-    @PostMapping("/sendCode")
+    @PostMapping("/sendVerifyCode")
     public ResultMap<Boolean> sendCode(@RequestParam String email, @RequestParam String appId) {
         EmailSendBO bo = new EmailSendBO();
-        bo.setEmailTitle("test");
-        bo.setToEmail("316531990@qq.com");
-        bo.setTemplateId("1");
+//        bo.setEmailTitle("test");
+//        bo.setToEmail("316531990@qq.com");
+//        bo.setTemplateId("1");
         Map<String,String> map = new HashMap<>();
         map.put("@username@","wph");
         bo.setSendContent(map);
@@ -106,6 +108,23 @@ public class AuthController {
         return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS, Boolean.TRUE);
     }
 
+    @GetMapping("/getVerifyCode")
+    public ResultMap<Boolean> getVerifyCode(@RequestParam String action,@RequestParam Integer type,@NotBlank(message = "接收者不能为空") @RequestParam String receiver,@RequestParam String appId) {
+        EmailCodeTypeEnum actionEnum = EmailCodeTypeEnum.getEnumByValue(action);
+        if (actionEnum == null) {
+            return new ResultMap<>(CommonConstant.ERROR, AuthConstant.EXCEPTION_MSG_CODE_ACTION_ERROR, false);
+        }
+        VerifyTypeEnum verifyTypeEnum = VerifyTypeEnum.getEnumByCode(type);
+        if (verifyTypeEnum == null) {
+            return new ResultMap<>(CommonConstant.ERROR, AuthConstant.EXCEPTION_MSG_CODE_TYPE_ERROR, false);
+        }
+        if (authService.getVerifyCode(actionEnum, verifyTypeEnum, receiver,appId)) {
+            return new ResultMap<>(CommonConstant.SUCCESS, VerifyTypeEnum.PHONE.code().equals(type) ?AuthConstant.SUCCESS_MSG_CODE_SEND:AuthConstant.SUCCESS_MSG_CODE_SEND_MAIL, true);
+        } else {
+            return new ResultMap<>(CommonConstant.ERROR, VerifyTypeEnum.PHONE.code().equals(type) ?AuthConstant.EXCEPTION_MSG_CODE_SEND_ERROR:AuthConstant.EXCEPTION_MAIL_CODE_SEND_ERROR, false);
+        }
+    }
+
 
     /**
      * 实时检查邮件验证码

+ 15 - 2
pdf-office-sso/src/main/java/cn/kdan/cloud/pdf/office/sso/service/AuthService.java

@@ -4,6 +4,7 @@ package cn.kdan.cloud.pdf.office.sso.service;
 import cn.kdan.cloud.pdf.office.common.dto.UserRegisterDTO;
 import cn.kdan.cloud.pdf.office.common.enums.EmailCodeTypeEnum;
 import cn.kdan.cloud.pdf.office.common.vo.TokenVO;
+import cn.kdan.cloud.pdf.office.sso.enums.VerifyTypeEnum;
 
 import javax.servlet.http.HttpServletRequest;
 import java.security.Principal;
@@ -19,14 +20,25 @@ public interface AuthService {
      * 邮箱登录
      *
      * @param email 邮箱
-     * @param code 验证码
+     * @param password 验证码
      * @param appId appid
      * @param platformType  1官网 2后台
      * @param request
      * @return TokenVO
      */
-    TokenVO emailLogin(String email, String code, String appId, String platformType, String deviceSign, HttpServletRequest request);
+    TokenVO emailLogin(String email, String password, String appId, String platformType, String deviceSign, HttpServletRequest request);
+
 
+    /**
+     * 发送验证码
+     *
+     * @param action  EmailCodeTypeEnum
+     * @param type VerifyTypeEnum
+     * @param receiver 邮箱
+     * @param appId appId 应用id
+     * @return boolean
+     */
+    boolean getVerifyCode(EmailCodeTypeEnum action, VerifyTypeEnum type, String receiver, String appId);
 
     /**
      * 登出(token失效,清除登录设备信息)
@@ -53,4 +65,5 @@ public interface AuthService {
      * @return
      */
     TokenVO emailRegister(UserRegisterDTO userRegisterDTO);
+
 }

+ 59 - 3
pdf-office-sso/src/main/java/cn/kdan/cloud/pdf/office/sso/service/impl/AuthServiceImpl.java

@@ -5,6 +5,8 @@ import cn.kdan.cloud.pdf.office.api.account.feign.OauthClientDetailsApi;
 import cn.kdan.cloud.pdf.office.api.account.feign.UserApi;
 import cn.kdan.cloud.pdf.office.api.account.vo.LoginDevice;
 import cn.kdan.cloud.pdf.office.api.account.vo.OauthClientDetails;
+import cn.kdan.cloud.pdf.office.api.email.bo.EmailSendBO;
+import cn.kdan.cloud.pdf.office.api.email.feign.EmailApi;
 import cn.kdan.cloud.pdf.office.common.constant.CommonConstant;
 import cn.kdan.cloud.pdf.office.common.dto.UserRegisterDTO;
 import cn.kdan.cloud.pdf.office.common.enums.EmailCodeTypeEnum;
@@ -16,6 +18,7 @@ import cn.kdan.cloud.pdf.office.common.utils.RedisUtils;
 import cn.kdan.cloud.pdf.office.common.vo.TokenVO;
 import cn.kdan.cloud.pdf.office.common.vo.UserInfoVO;
 import cn.kdan.cloud.pdf.office.sso.constant.AuthConstant;
+import cn.kdan.cloud.pdf.office.sso.enums.VerifyTypeEnum;
 import cn.kdan.cloud.pdf.office.sso.service.AuthService;
 import cn.kdan.cloud.pdf.office.sso.utils.TokenUtils;
 import com.alibaba.nacos.common.utils.CollectionUtils;
@@ -26,6 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.context.annotation.Lazy;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -73,6 +77,8 @@ public class AuthServiceImpl implements AuthService {
 
     @Autowired
     private TokenEndpoint tokenEndpoint;
+    @Autowired
+    private EmailApi emailApi;
 
 
     @Value("${security.oauth2.client.user-authorization-uri}")
@@ -124,16 +130,16 @@ public class AuthServiceImpl implements AuthService {
     }
 
     @Override
-    public TokenVO emailLogin(String email, String code, String appId, String platformType, String deviceSign,HttpServletRequest request) {
+    public TokenVO emailLogin(String email, String password, String appId, String platformType, String deviceSign,HttpServletRequest request) {
         //如果是管理平台就去查管理平台的用户表
         UserInfoVO userInfoVO = userApi.getByAppAccount(email,appId,platformType).getResult();
         //检查用户存在
         checkUser(userInfoVO);
         //检查邮件验证码
-        checkEmailCodeValid(EmailCodeTypeEnum.LOGIN,email,code);
+        //checkEmailCodeValid(EmailCodeTypeEnum.LOGIN,email,code);
         // 检查设备是否达到上限
         checkLoginDeviceNum(userInfoVO.getId(), deviceSign);
-        TokenVO vo = getTokenByUser(code, userInfoVO);
+        TokenVO vo = getTokenByUser(password, userInfoVO);
         //关联设备登录
         relateTokenAndDevice(vo.getAccess_token(), userInfoVO.getId(), deviceSign, appId);
         return vo;
@@ -156,6 +162,56 @@ public class AuthServiceImpl implements AuthService {
         throw new BackendRuntimeException(AuthConstant.EMAIL_REGISTER_ERROR);
     }
 
+    @Override
+    public boolean getVerifyCode(EmailCodeTypeEnum action, VerifyTypeEnum type, String receiver, String appId) {
+        boolean flag = false;
+        if (redisUtils.hexists(AuthConstant.VERIFY_CODE_TIME_OUT + action.value() + CommonConstant.STRIKE_THROUGH + appId, receiver)) {
+            throw new BackendRuntimeException(AuthConstant.VERIFY_CODE_SEND_TOO_QUICKLY);
+        }
+        String code = CommonUtils.generateVerifyCode();
+        switch (type) {
+            //发送手机验证码
+            case PHONE:
+                //忘记密码时手机验证 发送手机短信
+                break;
+            //发送邮件
+            case EMAIL:
+                //创建账号
+                EmailSendBO bo = new EmailSendBO();
+                bo.setToEmail(receiver);
+                handleEmailSendBO(action,bo,code);
+                if(emailApi.sendEmail(bo).getCode() == HttpStatus.OK.value()){
+                    flag = true;
+                };
+                break;
+            default:
+                break;
+        }
+        //存入缓存
+        if (flag) {
+            redisUtils.hset(AuthConstant.VERIFY_CODE_KEY + action.value() + CommonConstant.STRIKE_THROUGH + appId, receiver, code, AuthConstant.VERIFY_CODE_KEY_EXPIRE_TIME);
+            //再次发送计时
+            redisUtils.hset(AuthConstant.VERIFY_CODE_TIME_OUT + action.value() + CommonConstant.STRIKE_THROUGH + appId , receiver, "1", AuthConstant.VERIFY_CODE_KEY_RESEND_TIME);
+        }
+        return flag;
+    }
+
+    void handleEmailSendBO (EmailCodeTypeEnum action,EmailSendBO bo,String code) {
+        //设置事件
+        bo.setUseEvent(action.value());
+        //设置title
+        Map<String,String> titleMap = new HashMap<>();
+        //设置内容
+        Map<String,String> contentMap = new HashMap<>();
+        //注册
+        if(action.value().equals(EmailCodeTypeEnum.USER_REGISTER.value())){
+            contentMap.put("@code@",code);
+        }
+        bo.setSendTitleContent(titleMap);
+        //设置内容
+        bo.setSendContent(contentMap);
+    }
+
     @Resource
     @Lazy
     private TokenStore tokenStore;