Selaa lähdekoodia

1.分享加入功能
2.sms短信验证码使用缓存
3.重构新增账户代码

chenw 7 vuotta sitten
vanhempi
commit
e237790e64
24 muutettua tiedostoa jossa 962 lisäystä ja 77 poistoa
  1. 57 0
      applications/commons/commons-dto/src/main/java/com/usoftchina/saas/commons/dto/ShareAddDTO.java
  2. 19 0
      applications/commons/commons-server/pom.xml
  3. 194 0
      applications/commons/commons-server/src/main/java/com/usoftchina/saas/commons/controller/ShareController.java
  4. 39 0
      applications/commons/commons-server/src/main/java/com/usoftchina/saas/commons/utils/SHA1.java
  5. 104 0
      applications/commons/commons-server/src/main/java/com/usoftchina/saas/commons/utils/WeixinTokenUtil.java
  6. 81 0
      applications/commons/commons-server/src/test/java/com/usoftchina/saas/commons/controller/ShareControllerTest.java
  7. 56 0
      applications/commons/commons-server/src/test/java/com/usoftchina/saas/commons/utils/UrlBase64EncoderTest.java
  8. 9 0
      base-servers/account/account-api/src/main/java/com/usoftchina/saas/account/api/AccountApi.java
  9. 14 67
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/AccountController.java
  10. 14 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/RoleController.java
  11. 15 0
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/AccountService.java
  12. 181 4
      base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/AccountServiceImpl.java
  13. 11 1
      base-servers/account/account-server/src/main/resources/mapper/AccountMapper.xml
  14. 13 0
      base-servers/auth/auth-server/src/test/java/com/usoftchina/saas/auth/controller/AuthControllerTest.java
  15. 3 0
      base-servers/gateway-server/src/main/resources/application.yml
  16. 4 0
      base-servers/sms/sms-api/pom.xml
  17. 2 2
      base-servers/sms/sms-api/src/main/java/com/usoftchina/saas/sms/api/SmsApi.java
  18. 86 0
      base-servers/sms/sms-api/src/main/java/com/usoftchina/saas/sms/cache/SmsCache.java
  19. 1 1
      base-servers/sms/sms-server/src/main/java/com/usoftchina/saas/sms/controller/SmsController.java
  20. 1 1
      base-servers/sms/sms-server/src/test/java/com/usoftchina/saas/sms/api/SmsApiTest.java
  21. 48 0
      base-servers/sms/sms-server/src/test/java/com/usoftchina/saas/sms/cache/SmsCacheTest.java
  22. 3 1
      framework/core/src/main/java/com/usoftchina/saas/exception/ExceptionCode.java
  23. 6 0
      framework/core/src/main/java/com/usoftchina/saas/utils/StringUtils.java
  24. 1 0
      frontend/saas-portal-web/static/MP_verify_BMkQAHplMGROBlAn.txt

+ 57 - 0
applications/commons/commons-dto/src/main/java/com/usoftchina/saas/commons/dto/ShareAddDTO.java

@@ -0,0 +1,57 @@
+package com.usoftchina.saas.commons.dto;
+
+import java.io.Serializable;
+
+/**
+ * @Description 分享加入界面,提交传输对象
+ * @Author chenwei
+ * @Date 2018/12/19
+ */
+public class ShareAddDTO implements Serializable {
+
+    private String username;
+    private String mobile;
+    private String validCode;
+    private String roleId;
+    private Long companyId;
+
+    public Long getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(Long companyId) {
+        this.companyId = companyId;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getMobile() {
+        return mobile;
+    }
+
+    public void setMobile(String mobile) {
+        this.mobile = mobile;
+    }
+
+    public String getValidCode() {
+        return validCode;
+    }
+
+    public void setValidCode(String validCode) {
+        this.validCode = validCode;
+    }
+
+    public String getRoleId() {
+        return roleId;
+    }
+
+    public void setRoleId(String roleId) {
+        this.roleId = roleId;
+    }
+}

+ 19 - 0
applications/commons/commons-server/pom.xml

@@ -23,6 +23,14 @@
             <groupId>com.usoftchina.saas</groupId>
             <artifactId>server-starter</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>auth-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usoftchina.saas</groupId>
+            <artifactId>sms-api</artifactId>
+        </dependency>
         <!-- db -->
         <dependency>
             <groupId>mysql</groupId>
@@ -79,6 +87,17 @@
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
         </dependency>
+        <!-- ZXING 二维码 -->
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>core</artifactId>
+            <version>3.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>javase</artifactId>
+            <version>3.3.0</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 194 - 0
applications/commons/commons-server/src/main/java/com/usoftchina/saas/commons/controller/ShareController.java

@@ -0,0 +1,194 @@
+package com.usoftchina.saas.commons.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.client.j2se.MatrixToImageWriter;
+import com.google.zxing.common.BitMatrix;
+import com.usoftchina.saas.account.api.AccountApi;
+import com.usoftchina.saas.auth.common.crypto.base64.UrlBase64;
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.commons.dto.ShareAddDTO;
+import com.usoftchina.saas.commons.utils.WeixinTokenUtil;
+import com.usoftchina.saas.context.BaseContextHolder;
+import com.usoftchina.saas.exception.BizException;
+import com.usoftchina.saas.exception.ExceptionCode;
+import com.usoftchina.saas.sms.api.SmsApi;
+import com.usoftchina.saas.sms.cache.SmsCache;
+import com.usoftchina.saas.sms.dto.SmsDTO;
+import com.usoftchina.saas.utils.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Description 分享加入
+ * @Author chenwei
+ * @Date 2018/12/19
+ */
+@Controller
+@RequestMapping("/share")
+public class ShareController {
+
+    @Autowired
+    private AccountApi accountApi;
+    @Autowired
+    private SmsApi smsApi;
+
+    //验证码短信模板
+    private final String validTemplateCode = "SMS_152856542";
+
+    /**
+     * 生成分享二维码
+     * @param response
+     * @param basePath
+     */
+    @GetMapping("/qrcode")
+    public void qrcode(HttpServletResponse response,String companyName, String basePath, @RequestParam(value = "delay", defaultValue = "1") Long delay){
+        Long companyId = BaseContextHolder.getCompanyId();
+        String username = BaseContextHolder.getUserName();
+        try {
+            OutputStream outputStream = response.getOutputStream();
+            buildQrcode(basePath, username, companyId, delay, companyName, outputStream);
+            outputStream.flush();
+            outputStream.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 将前台传入的encode参数decode并校验,返回给前端
+     * @param param
+     * @return
+     */
+    @PostMapping("/valid/param")
+    @ResponseBody
+    public Result validParam(String param){
+        if (!StringUtils.isEmpty(param)){
+            String data = new String(UrlBase64.decode(param));
+            Map<String, String> paramData = parseParam(data);
+            return Result.success(paramData);
+        }
+        return Result.error(ExceptionCode.ILLEGAL_ARGUMENTS);
+    }
+
+    /**
+     * 生成微信需要的签名
+     * @param targetUrl
+     * @return
+     */
+    @GetMapping("/weixin/ticket")
+    @ResponseBody
+    public Result getWXTicket(@RequestParam("targetUrl") String targetUrl){
+        Map<String, String> map = null;
+        try {
+            map = WeixinTokenUtil.getConfigData(targetUrl);
+            return Result.success(map);
+        } catch (Exception e) {
+            return Result.error("处理失败");
+        }
+    }
+
+    /**
+     * 获取短信验证码
+     * @param mobile
+     * @return
+     */
+    @PostMapping("/getSmsCode")
+    @ResponseBody
+    public Result getSmsCode(String mobile){
+        String validCode = StringUtils.createValidCode(6);
+        SmsDTO smsDTO = new SmsDTO();
+        smsDTO.setSignName("优软云");
+        smsDTO.setMobile(mobile);
+        smsDTO.setTemplateCode(validTemplateCode);
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("code", validCode);
+        smsDTO.setTemplateParam(jsonObject.toJSONString());
+        //加入redis缓存,有效期5分钟
+        SmsCache smsCache = SmsCache.of(mobile);
+        smsCache.set(validCode, 60 * 5);
+        Result result = smsApi.sendMsg(smsDTO);
+        return Result.success();
+    }
+
+    /**
+     * 提交
+     * @param shareAddDTO
+     * @return
+     */
+    @PostMapping("/submit")
+    @ResponseBody
+    public Result submit(@RequestBody ShareAddDTO shareAddDTO){
+        return accountApi.shareJoin(shareAddDTO);
+    }
+
+
+    /**
+     * 生成二维码
+     * @param basePath
+     * @param username
+     * @param companyId
+     * @param outputStream
+     */
+    private void buildQrcode(String basePath, String username, Long companyId, Long delay, String companyName, OutputStream outputStream) throws WriterException, IOException {
+        String params = "username=" + username + "&companyId=" + companyId + "&timestamp=" + new Date().getTime() + "&delay=" + delay + "&companyName=" + companyName;
+        String encodeParams = new String(UrlBase64.encode(params.getBytes()));
+//        String text = basePath + "/xxx.html" + "?param=" + encodeParams;
+        String text = "https://www.baidu.com";
+        int width = 140;
+        int height = 140;
+        String format = "png";
+        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
+        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
+        hints.put(EncodeHintType.MARGIN, 1);
+        //生成矩阵
+        BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
+        //输出图像
+        MatrixToImageWriter.writeToStream(bitMatrix, format, outputStream);
+    }
+
+    /**
+     * 解析请求的参数
+     * @param data
+     * @return
+     */
+    private Map<String,String> parseParam(String data) {
+        Map<String, String> map = new HashMap<String, String>();
+        int firstEndIndex = data.indexOf("&");
+        int secondEndIndex = data.indexOf("&", firstEndIndex + 1);
+        int thirdEndIndex = data.indexOf("&", secondEndIndex + 1);
+        int lastEndIndex = data.indexOf("&", thirdEndIndex + 1);
+        map.put("username", data.substring(9, firstEndIndex));
+        map.put("companyId", data.substring(firstEndIndex + 11, secondEndIndex));
+        map.put("timestamp", data.substring(secondEndIndex + 11, thirdEndIndex));
+        map.put("delay", data.substring(thirdEndIndex + 7, lastEndIndex));
+        map.put("companyName", data.substring(lastEndIndex + 13));
+
+        /* 校验参数合法性 */
+        //1.校验参数值不为空
+        if (StringUtils.isEmpty(map.get("username")) || StringUtils.isEmpty(map.get("companyId"))
+                || StringUtils.isEmpty(map.get("timestamp")) || StringUtils.isEmpty(map.get("delay"))){
+            throw new BizException(ExceptionCode.ILLEGAL_ARGUMENTS);
+        }
+        //2.校验有效期
+        Long createTime = Long.parseLong(map.get("timestamp"));
+        Long delay = Long.parseLong(map.get("delay"));
+        Long expireTime = createTime + delay * 24 * 60 * 60 * 1000;
+        if (expireTime < new Date().getTime()){
+            throw new BizException(ExceptionCode.ILLEGAL_ARGUMENTS);
+        }
+        return map;
+    }
+
+}

+ 39 - 0
applications/commons/commons-server/src/main/java/com/usoftchina/saas/commons/utils/SHA1.java

@@ -0,0 +1,39 @@
+package com.usoftchina.saas.commons.utils;
+
+import java.security.MessageDigest;
+
+/**
+ * @Description 微信公众平台用到的SHA1加密算法
+ * @Author chenwei
+ * @Date 2018/12/20
+ */
+public class SHA1 {
+
+    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
+            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+    private static String getFormattedText(byte[] bytes) {
+        int len = bytes.length;
+        StringBuilder buf = new StringBuilder(len * 2);
+        // 把密文转换成十六进制的字符串形式
+        for (int j = 0; j < len; j++) {
+            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
+            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
+        }
+        return buf.toString();
+    }
+
+    public static String encode(String str) {
+        if (str == null) {
+            return null;
+        }
+        try {
+            MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
+            messageDigest.update(str.getBytes());
+            return getFormattedText(messageDigest.digest());
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}

+ 104 - 0
applications/commons/commons-server/src/main/java/com/usoftchina/saas/commons/utils/WeixinTokenUtil.java

@@ -0,0 +1,104 @@
+package com.usoftchina.saas.commons.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.usoftchina.saas.utils.http.HttpUtil;
+
+import java.security.MessageDigest;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * @Description 生成微信token
+ * @Author chenwei
+ * @Date 2018/12/19
+ */
+public class WeixinTokenUtil {
+
+    public final static String GetPageAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";
+    public final static String GetPageJSapiTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
+    public final static String SOURCE_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
+    public final static String APPID = "wxbc1f8607137d3b8a";
+    public final static String APPSECRET = "cadf13c4e21c2c122cb2341b341e5c22";
+
+    /**
+     * 获取accessToken
+     * @param appId
+     * @param appSecret
+     * @return
+     * @throws Exception
+     */
+    public static String getAccessToken(String appId, String appSecret) throws Exception {
+        String requestUrl = GetPageAccessTokenUrl.replace("APPID", appId).replace("SECRET", appSecret);
+        HttpUtil.Response response = HttpUtil.sendGetRequest(requestUrl, null);
+        if (response.getStatusCode() == 200){
+            JSONObject jsonObject = (JSONObject) JSONObject.parse(response.getResponseText());
+            return jsonObject.getString("access_token");
+        }
+        return null;
+    }
+
+    /**
+     * 获取ticket
+     * @param accessToken
+     * @return
+     * @throws Exception
+     */
+    public static Map<String, String> getJsapiTicket(String accessToken) throws Exception {
+        Map<String, String> result = new HashMap<String, String>();
+        String requestUrl = GetPageJSapiTicketUrl.replace("ACCESS_TOKEN", accessToken);
+        HttpUtil.Response response = HttpUtil.sendGetRequest(requestUrl, null);
+        if (response.getStatusCode() == 200){
+            JSONObject jsonObject = (JSONObject) JSONObject.parse(response.getResponseText());
+            result.put("errCode", jsonObject.getString("errcode"));
+            result.put("errMsg", jsonObject.getString("errmsg"));
+            result.put("ticket", jsonObject.getString("ticket"));
+            result.put("expires_in", jsonObject.getString("expires_in"));
+            return result;
+        }
+        return result;
+    }
+
+    /**
+     * 生成微信需要的config参数
+     * @param targetUrl
+     * @return
+     * @throws Exception
+     */
+    public static Map<String, String> getConfigData(String targetUrl) throws Exception {
+        String noncestr = generateString(new Random(), SOURCE_CHARACTERS, 32);
+        Long timestamp = new Date().getTime();
+        //accessToken
+        String accessToken = getAccessToken(APPID, APPSECRET);
+        Map<String, String> map = getJsapiTicket(accessToken);
+
+        String str = "jsapi_ticket=" + map.get("ticket") + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + targetUrl;
+        String signature = SHA1.encode(str);
+
+        Map<String, String> resultMap = new HashMap<String, String>();
+        resultMap.put("timestamp", String.valueOf(timestamp));
+        resultMap.put("accessToken", accessToken);
+        resultMap.put("ticket", map.get("ticket"));
+        resultMap.put("noncestr", noncestr);
+        resultMap.put("signature", signature);
+        resultMap.put("appId", APPID);
+        return resultMap;
+    }
+
+    /**
+     * 生成指定位数的随机字符串
+     * @param random
+     * @param characters
+     * @param length
+     * @return
+     */
+    public static String generateString(Random random, String characters, int length){
+        char[] text = new char[length];
+        for (int i = 0; i < length; i++) {
+            text[i] = characters.charAt(random.nextInt(characters.length()));
+        }
+        return new String(text);
+    }
+
+}

+ 81 - 0
applications/commons/commons-server/src/test/java/com/usoftchina/saas/commons/controller/ShareControllerTest.java

@@ -0,0 +1,81 @@
+package com.usoftchina.saas.commons.controller;
+
+import com.usoftchina.saas.auth.common.crypto.base64.UrlBase64;
+import com.usoftchina.saas.auth.common.crypto.base64.UrlBase64Encoder;
+import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.commons.dto.ShareAddDTO;
+import com.usoftchina.saas.test.BaseControllerTest;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MvcResult;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 分享加入controller测试
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class ShareControllerTest extends BaseControllerTest {
+
+    private final String PARAMS = "username=陈炜&companyId=262&timestmap=" + new Date().getTime() + "&delay=1&companyName=陈炜";
+    private final String mobile = "18702604854";
+
+    @Test
+    public void qrcode() throws Exception {
+        mockMvc.perform(get("/share/qrcode")
+                .accept(MediaType.ALL)
+                .contentType(MediaType.ALL))
+                .andExpect(isSuccess());
+    }
+
+    @Test
+    public void validParam() throws Exception {
+        String param = new String(UrlBase64.encode(PARAMS.getBytes()));
+        mockMvc.perform(post("/share/valid/param")
+               .param("param", param))
+               .andExpect(isSuccess())
+               .andReturn();
+    }
+
+    @Test
+    public void getWXTicket() throws Exception {
+        MvcResult mvcResult = mockMvc.perform(get("/share/weixin/ticket")
+               .param("basePath", "https://saas.usoftchina.com"))
+               .andExpect(isSuccess())
+               .andReturn();
+        Result<HashMap> result = result(mvcResult, HashMap.class);
+        System.out.println(result);
+    }
+
+    @Test
+    public void getSmsCode() throws Exception {
+        mockMvc.perform(post("/share/getSmsCode")
+                .param("mobile", "18702604709"))
+                .andExpect(isSuccess())
+                .andReturn();
+    }
+
+    @Test
+    public void submit() throws Exception {
+        ShareAddDTO shareAddDTO = new ShareAddDTO();
+        shareAddDTO.setCompanyId(262L);
+        shareAddDTO.setUsername("何炎");
+        shareAddDTO.setMobile("18702604709");
+        shareAddDTO.setValidCode("123456");
+        shareAddDTO.setRoleId("0");
+
+        mockMvc.perform(requestBody("/share/submit", shareAddDTO))
+               .andExpect(isSuccess())
+               .andReturn();
+    }
+
+}

+ 56 - 0
applications/commons/commons-server/src/test/java/com/usoftchina/saas/commons/utils/UrlBase64EncoderTest.java

@@ -0,0 +1,56 @@
+package com.usoftchina.saas.commons.utils;
+
+import com.usoftchina.saas.auth.common.crypto.base64.UrlBase64;
+import org.junit.Test;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Description 测试URLEncode
+ * @Author chenwei
+ * @Date 2018/12/19
+ */
+public class UrlBase64EncoderTest {
+
+    private final String PARAMS = "username=陈炜&companyId=262&timestmap=" + new Date().getTime() + "&delay=1&companyName=陈炜";
+
+    @Test
+    public void testA_UrlEncocde(){
+        byte[] encodeBytes = UrlBase64.encode(PARAMS.getBytes());
+        String encodeStr = new String(encodeBytes);
+        System.out.println("encodeStr:========" + encodeStr + "============");
+
+        byte[] decodeBytes = UrlBase64.decode(encodeStr);
+        String decodeStr = new String(decodeBytes);
+        System.out.println("decodeBytes:========" + decodeStr + "============");
+    }
+    
+    @Test
+    public void testB_parseParam(){
+        Map<String, String> map = new HashMap<String, String>();
+        int firstEndIndex = PARAMS.indexOf("&");
+        int secondEndIndex = PARAMS.indexOf("&", firstEndIndex + 1);
+        int thirdEndIndex = PARAMS.indexOf("&", secondEndIndex + 1);
+        int lastEndIndex = PARAMS.indexOf("&", thirdEndIndex + 1);
+
+        map.put("username", PARAMS.substring(9, firstEndIndex));
+        map.put("companyId", PARAMS.substring(firstEndIndex + 11, secondEndIndex));
+        map.put("timestamp", PARAMS.substring(secondEndIndex + 11, lastEndIndex));
+        map.put("delay", PARAMS.substring(thirdEndIndex + 7, lastEndIndex));
+        map.put("companyName", PARAMS.substring(lastEndIndex + 13));
+        System.out.println(map);
+    }
+
+    @Test
+    public void testC_Timeconpare(){
+        Long createTime = 1545196813279L;
+        Long expireTime = createTime + 5 * 60 * 1000;
+        Long now = new Date().getTime();
+        System.out.println("NOW:==========" + now + "==========");
+        System.out.println("expireTime:==========" + expireTime + "==========");
+        System.out.println(now.compareTo(expireTime) > 0);
+    }
+
+}

+ 9 - 0
base-servers/account/account-api/src/main/java/com/usoftchina/saas/account/api/AccountApi.java

@@ -5,6 +5,7 @@ import com.usoftchina.saas.account.dto.AccountDTO;
 import com.usoftchina.saas.account.dto.AccountRegDTO;
 import com.usoftchina.saas.account.dto.AccountUpdateDTO;
 import com.usoftchina.saas.base.Result;
+import com.usoftchina.saas.commons.dto.ShareAddDTO;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.*;
 
@@ -96,4 +97,12 @@ public interface AccountApi {
      */
     @PostMapping("/bind/roles")
     Result bindRoles(@RequestParam("accountId") Long accountId, @RequestParam("roleIds") String roleIds);
+
+    /**
+     * 二维码分享加入
+     * @param shareAddDTO
+     * @return
+     */
+    @PostMapping("/account/share/join")
+    Result shareJoin(@RequestBody ShareAddDTO shareAddDTO);
 }

+ 14 - 67
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/AccountController.java

@@ -1,9 +1,7 @@
 package com.usoftchina.saas.account.controller;
 
-import com.alibaba.fastjson.JSONObject;
 import com.usoftchina.saas.account.dto.*;
 import com.usoftchina.saas.account.po.Account;
-import com.usoftchina.saas.account.po.Company;
 import com.usoftchina.saas.account.po.RoleResource;
 import com.usoftchina.saas.account.service.AccountService;
 import com.usoftchina.saas.account.service.CompanyService;
@@ -12,17 +10,16 @@ import com.usoftchina.saas.account.vo.CompanyBaseVO;
 import com.usoftchina.saas.auth.client.annotation.IgnoreAuth;
 import com.usoftchina.saas.base.Result;
 import com.usoftchina.saas.commons.dto.ListReqDTO;
+import com.usoftchina.saas.commons.dto.ShareAddDTO;
 import com.usoftchina.saas.context.BaseContextHolder;
 import com.usoftchina.saas.exception.BizException;
 import com.usoftchina.saas.exception.ExceptionCode;
 import com.usoftchina.saas.page.PageDefault;
 import com.usoftchina.saas.page.PageRequest;
 import com.usoftchina.saas.sms.api.SmsApi;
-import com.usoftchina.saas.sms.dto.SmsDTO;
 import com.usoftchina.saas.utils.BeanMapper;
 import com.usoftchina.saas.utils.CollectionUtils;
 import com.usoftchina.saas.utils.RegexpUtils;
-import com.usoftchina.saas.utils.StringUtils;
 import com.usoftchina.sso.api.SsoUserApi;
 import com.usoftchina.sso.api.SsoUserSpaceApi;
 import com.usoftchina.sso.dto.*;
@@ -128,69 +125,7 @@ public class AccountController {
      */
     @PostMapping("/register/add")
     public Result AddAccount(@RequestBody AccountAddDTO accountAddDTO) {
-        String mobile = accountAddDTO.getMobile();
-        Account account = null;
-        // 根据手机号、邮箱、用户名片段判断是否已注册
-        boolean checked = accountService.findByUsernameOrMobileOrEmail(accountAddDTO.getUsername(), accountAddDTO.getMobile(), accountAddDTO.getEmail());
-        //不存在 ——> 保存 , 存在 ——> 更新
-        if (!checked) {
-            account = BeanMapper.map(accountAddDTO, Account.class);
-            account.setEnabled(true);
-            accountService.save(account);
-            if (!accountAddDTO.isHasRegister()) {
-                //1.添加至优软云
-                String password = StringUtils.createInitPassword(mobile.substring(mobile.length() - 3, mobile.length()));
-                Company company = companyService.findByPrimaryKey(BaseContextHolder.getCompanyId());
-                String companyName = company.getName();
-
-                //可能存在开通企业时UU号同步到优软云出错的情况,再重新同步一次
-                if (company.getUu() == null) {
-                    Account accountTmp = accountService.findByPrimaryKey(company.getCreatorId());
-                    ssoUserSpaceApi.registerLogin(companyName, company.getBusinessCode(), accountTmp.getUu());
-                    SsoUserSpaceList ssoUserSpaceList = ssoUserApi.getUserSpacesByMobile(accountTmp.getMobile());
-                    List<SsoUserSpace> ssoUserSpaces = ssoUserSpaceList.getSpaces();
-                    if (ssoUserSpaces.size() > 0) {
-                        for (SsoUserSpace ssoUserspace : ssoUserSpaces) {
-                            if (companyName.equals(ssoUserspace.getSpaceName())) {
-                                company.setUu(ssoUserspace.getSpaceUU());
-                                companyService.updateUUByPrimaryKey(company.getId(), ssoUserspace.getSpaceUU());
-                            }
-                        }
-                    }
-                }
-                SsoResult result = ssoUserApi.add("add", "sp", accountAddDTO.getRealname(), mobile, password, company.getUu());
-                //2.调用短信服务,将密码以短信的形式发送到用户的手机上
-                if (result.isSuccess()) {
-                    SmsDTO smsDTO = new SmsDTO();
-                    smsDTO.setMobile(mobile);
-                    smsDTO.setSignName("优软云");
-                    smsDTO.setTemplateCode(msgTemplateCode);
-                    JSONObject jsonObject = new JSONObject();
-                    jsonObject.put("password", password);
-                    smsDTO.setTemplateParam(jsonObject.toJSONString());
-                    Result sendResult = smsApi.sendRegisterMsg(smsDTO);
-                    if (!sendResult.isSuccess()) {
-                        return sendResult;
-                    }
-                }
-            }
-        }else{
-            Account accountTemp = accountService.findByMobile(accountAddDTO.getMobile());
-            if (accountTemp == null){
-                accountTemp = accountService.findByEmail(accountAddDTO.getEmail());
-            }
-            account = BeanMapper.map(accountAddDTO, Account.class);
-            account.setEnabled(true);
-            account.setId(accountTemp.getId());
-            accountService.updateByPrimaryKeySelective(account);
-        }
-        account = accountService.findByMobile(accountAddDTO.getMobile());
-        //绑定企业
-        accountService.bindCompany(account.getId(), BaseContextHolder.getCompanyId());
-        //绑定角色
-        accountService.bindRoles(account.getId(), accountAddDTO.getRoleIds());
-        accountService.clearCache(account.getId());
-        return Result.success();
+        return accountService.addAccount(accountAddDTO);
     }
 
     /**
@@ -530,4 +465,16 @@ public class AccountController {
         accountService.clearCache(BaseContextHolder.getUserId());
         return Result.success();
     }
+
+    /**
+     * 分享加入
+     * @param shareAddDTO
+     * @return
+     */
+    @PostMapping("/share/join")
+    @IgnoreAuth
+    public Result shareJoin(@RequestBody ShareAddDTO shareAddDTO){
+        accountService.shareJoin(shareAddDTO);
+        return Result.success();
+    }
 }

+ 14 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/controller/RoleController.java

@@ -114,6 +114,20 @@ public class RoleController {
         return Result.success(BeanMapper.mapList(roles, RoleDTO.class));
     }
 
+    @GetMapping("/list/{id}")
+    public Result<List<RoleDTO>> getByCompanyId(@PathVariable("id") Long companyId){
+        List<Role> roles = roleService.findByCompanyId(companyId);
+        if (CollectionUtils.isEmpty(roles)) {
+            return Result.success();
+        }
+        for (int i = 0; i < roles.size(); i++){
+            if (roles.get(i).getType() == 0){
+                roles.remove(i);
+            }
+        }
+        return Result.success(BeanMapper.mapList(roles, RoleDTO.class));
+    }
+
     /**
      * 角色绑定资源
      *

+ 15 - 0
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/AccountService.java

@@ -1,10 +1,13 @@
 package com.usoftchina.saas.account.service;
 
 import com.github.pagehelper.PageInfo;
+import com.usoftchina.saas.account.dto.AccountAddDTO;
 import com.usoftchina.saas.account.dto.AccountRoleDTO;
 import com.usoftchina.saas.account.po.Account;
 import com.usoftchina.saas.account.po.RoleResource;
+import com.usoftchina.saas.base.Result;
 import com.usoftchina.saas.commons.dto.ListReqDTO;
+import com.usoftchina.saas.commons.dto.ShareAddDTO;
 import com.usoftchina.saas.page.PageRequest;
 
 import java.util.List;
@@ -202,4 +205,16 @@ public interface AccountService {
      * @param status
      */
     void updateBindCompanyStatus(Long accountId, Long companyId, String status);
+
+    /**
+     * 新增用户,已注册的更新,未注册的后台自动注册
+     * @param accountAddDTO
+     */
+    Result addAccount(AccountAddDTO accountAddDTO);
+
+    /**
+     * 分享加入
+     * @param shareAddDTO
+     */
+    void shareJoin(ShareAddDTO shareAddDTO);
 }

+ 181 - 4
base-servers/account/account-server/src/main/java/com/usoftchina/saas/account/service/impl/AccountServiceImpl.java

@@ -1,21 +1,40 @@
 package com.usoftchina.saas.account.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import com.usoftchina.saas.account.cache.AccountCache;
+import com.usoftchina.saas.account.dto.AccountAddDTO;
 import com.usoftchina.saas.account.dto.AccountRoleDTO;
 import com.usoftchina.saas.account.mapper.AccountCompanyMapper;
 import com.usoftchina.saas.account.mapper.AccountMapper;
 import com.usoftchina.saas.account.mapper.AccountRoleMapper;
 import com.usoftchina.saas.account.mapper.RoleResourceMapper;
 import com.usoftchina.saas.account.po.Account;
+import com.usoftchina.saas.account.po.Company;
 import com.usoftchina.saas.account.po.Role;
 import com.usoftchina.saas.account.po.RoleResource;
 import com.usoftchina.saas.account.service.AccountService;
+import com.usoftchina.saas.account.service.CompanyService;
 import com.usoftchina.saas.account.service.RoleService;
+import com.usoftchina.saas.base.Result;
 import com.usoftchina.saas.commons.dto.ListReqDTO;
+import com.usoftchina.saas.commons.dto.ShareAddDTO;
 import com.usoftchina.saas.context.BaseContextHolder;
+import com.usoftchina.saas.exception.BizException;
+import com.usoftchina.saas.exception.ExceptionCode;
 import com.usoftchina.saas.page.PageRequest;
+import com.usoftchina.saas.sms.api.SmsApi;
+import com.usoftchina.saas.sms.cache.SmsCache;
+import com.usoftchina.saas.sms.dto.SmsDTO;
+import com.usoftchina.saas.utils.BeanMapper;
+import com.usoftchina.saas.utils.StringUtils;
+import com.usoftchina.sso.api.SsoUserApi;
+import com.usoftchina.sso.api.SsoUserSpaceApi;
+import com.usoftchina.sso.dto.SsoCheckMobile;
+import com.usoftchina.sso.dto.SsoResult;
+import com.usoftchina.sso.dto.SsoUserSpace;
+import com.usoftchina.sso.dto.SsoUserSpaceList;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -23,6 +42,7 @@ import org.springframework.util.DigestUtils;
 
 import java.util.Date;
 import java.util.List;
+import java.util.Optional;
 
 /**
  * @author yingp
@@ -33,18 +53,25 @@ public class AccountServiceImpl implements AccountService {
 
     @Autowired
     private AccountMapper accountMapper;
-
     @Autowired
     private AccountCompanyMapper accountCompanyMapper;
-
     @Autowired
     private AccountRoleMapper accountRoleMapper;
-
     @Autowired
     private RoleService roleService;
-
     @Autowired
     private RoleResourceMapper roleResourceMapper;
+    @Autowired
+    private CompanyService companyService;
+    @Autowired
+    private SsoUserSpaceApi ssoUserSpaceApi;
+    @Autowired
+    private SsoUserApi ssoUserApi;
+    @Autowired
+    private SmsApi smsApi;
+
+    //注册短信模板
+    private final String msgTemplateCode = "SMS_152288990";
 
     @Override
     public boolean save(Account account) {
@@ -214,4 +241,154 @@ public class AccountServiceImpl implements AccountService {
         accountMapper.updateBindCompanyStatus(accountId, companyId, status);
     }
 
+    @Override
+    public Result addAccount(AccountAddDTO accountAddDTO){
+        Account account = new Account();
+        // 根据手机号、邮箱、用户名片段判断是否已注册
+        boolean checked = findByUsernameOrMobileOrEmail(accountAddDTO.getUsername(), accountAddDTO.getMobile(), accountAddDTO.getEmail());
+        //不存在 ——> 保存 , 存在 ——> 更新
+        addOrUpdate(checked, accountAddDTO);
+
+        account = findByMobile(accountAddDTO.getMobile());
+        //绑定企业
+        bindCompany(account.getId(), BaseContextHolder.getCompanyId());
+        //绑定角色
+        bindRoles(account.getId(), accountAddDTO.getRoleIds());
+        clearCache(account.getId());
+        return Result.success();
+    }
+
+    /**
+     * 保存账户: 存在则更新,不存在自动注册
+     * @param checked
+     * @param accountAddDTO
+     */
+    private void addOrUpdate(boolean checked, AccountAddDTO accountAddDTO){
+        Account account = new Account();
+        if (!checked) {
+            account = BeanMapper.map(accountAddDTO, Account.class);
+            account.setEnabled(true);
+            save(account);
+            if (!accountAddDTO.isHasRegister()) {
+                //用户未注册优软云
+                registerAccount(accountAddDTO.getMobile(), accountAddDTO.getRealname());
+            }
+        }else{
+            Account accountTemp = findByMobile(accountAddDTO.getMobile());
+            if (accountTemp == null){
+                accountTemp = findByEmail(accountAddDTO.getEmail());
+            }
+            account = BeanMapper.map(accountAddDTO, Account.class);
+            account.setEnabled(true);
+            account.setId(accountTemp.getId());
+            updateByPrimaryKeySelective(account);
+        }
+    }
+
+    /**
+     * 用户未注册优软云,后台自动注册
+     * @param mobile
+     * @param realname
+     */
+    private void registerAccount(String mobile, String realname){
+        //1.添加至优软云
+        String password = StringUtils.createInitPassword(mobile.substring(mobile.length() - 3, mobile.length()));
+        Company company = companyService.findByPrimaryKey(BaseContextHolder.getCompanyId());
+        String companyName = company.getName();
+
+        //可能存在开通企业时UU号同步到优软云出错的情况,再重新同步一次
+        if (company.getUu() == null) {
+            Account accountTmp = findByPrimaryKey(company.getCreatorId());
+            ssoUserSpaceApi.registerLogin(companyName, company.getBusinessCode(), accountTmp.getUu());
+            SsoUserSpaceList ssoUserSpaceList = ssoUserApi.getUserSpacesByMobile(accountTmp.getMobile());
+            List<SsoUserSpace> ssoUserSpaces = ssoUserSpaceList.getSpaces();
+            if (ssoUserSpaces.size() > 0) {
+                for (SsoUserSpace ssoUserspace : ssoUserSpaces) {
+                    if (companyName.equals(ssoUserspace.getSpaceName())) {
+                        company.setUu(ssoUserspace.getSpaceUU());
+                        companyService.updateUUByPrimaryKey(company.getId(), ssoUserspace.getSpaceUU());
+                    }
+                }
+            }
+        }
+        SsoResult result = ssoUserApi.add("add", "sp", realname, mobile, password, company.getUu());
+        //2.调用短信服务,将密码以短信的形式发送到用户的手机上
+        if (result.isSuccess()) {
+            SmsDTO smsDTO = new SmsDTO();
+            smsDTO.setMobile(mobile);
+            smsDTO.setSignName("优软云");
+            smsDTO.setTemplateCode(msgTemplateCode);
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("password", password);
+            smsDTO.setTemplateParam(jsonObject.toJSONString());
+            smsApi.sendMsg(smsDTO);
+        }
+    }
+
+    /**
+     * 分享加入
+     * @param shareAddDTO
+     */
+    @Override
+    public void shareJoin(ShareAddDTO shareAddDTO) {
+        String mobile = shareAddDTO.getMobile();
+        String realname = shareAddDTO.getUsername();
+        Long companyId = shareAddDTO.getCompanyId();
+        //1.校验短信验证码是否正确
+        validSmsCode(shareAddDTO.getMobile(), shareAddDTO.getValidCode());
+
+
+
+        //2.开通
+        //2.1构造AccountAddDTO对象
+        AccountAddDTO accountAddDTO = new AccountAddDTO();
+        accountAddDTO.setUsername(mobile);
+        accountAddDTO.setMobile(mobile);
+        accountAddDTO.setRealname(realname);
+        accountAddDTO.setRoleIds(shareAddDTO.getRoleId());
+        //2.2增加用户
+        //根据手机号、邮箱、用户名片段判断是否已注册
+        boolean checked = findByUsernameOrMobileOrEmail(accountAddDTO.getUsername(), accountAddDTO.getMobile(), accountAddDTO.getEmail());
+        if (!checked){
+            SsoCheckMobile ssoCheckMobile = ssoUserApi.checkMobile(mobile);
+            if (ssoCheckMobile.isHasRegister()){
+                accountAddDTO.setHasRegister(true);
+            }
+        }else {
+            /* 是否已加入企业 */
+            Account account = findByMobile(mobile);
+            boolean hasBind = companyService.hasBind(account.getId(), companyId);
+            if (hasBind){
+                throw new BizException(ExceptionCode.HAS_BIND_COMPANY);
+            }
+        }
+
+        //不存在 ——> 保存 , 存在 ——> 更新
+        addOrUpdate(checked, accountAddDTO);
+
+        Account account = findByMobile(accountAddDTO.getMobile());
+        //绑定企业
+        bindCompany(account.getId(), companyId);
+        //绑定角色
+        bindRoles(account.getId(), accountAddDTO.getRoleIds());
+        //清除缓存
+        clearCache(account.getId());
+    }
+
+    /**
+     * 校验短信验证码准确性
+     * @param mobile
+     * @param smsCode
+     */
+    private void validSmsCode(String mobile, String smsCode){
+        SmsCache smsCache = SmsCache.of(mobile);
+        Optional<String> optional = smsCache.getCache();
+        if (!optional.isPresent()){
+            throw new BizException(ExceptionCode.SMS_VALIDCODE_EXPIRE);
+        }
+        if (!optional.get().equals(smsCode)){
+            throw new BizException(ExceptionCode.SMS_VALIDCODE_ERROR);
+        }
+    }
+
 }

+ 11 - 1
base-servers/account/account-server/src/main/resources/mapper/AccountMapper.xml

@@ -208,7 +208,17 @@
     </select>
     <select id="findByUsernameOrMobileOrEmail" resultType="int">
         SELECT COUNT(*) FROM AC_ACCOUNT
-        WHERE USERNAME = #{username} OR MOBILE = #{mobile} OR EMAIL = #{email};
+        <where>
+            <if test="username != null">
+                username = #{username}
+            </if>
+            <if test="email != null">
+                or email = #{email}
+            </if>
+            <if test="mobile != null">
+                or mobile = #{mobile}
+            </if>
+        </where>
     </select>
     <update id="updateBindCompanyStatus">
         UPDATE AC_ACCOUNT_COMPANY SET STATUS = #{status} WHERE ACCOUNT_ID = #{accountId} AND COMPANY_ID = #{companyId}

+ 13 - 0
base-servers/auth/auth-server/src/test/java/com/usoftchina/saas/auth/controller/AuthControllerTest.java

@@ -14,6 +14,8 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 import org.springframework.test.web.servlet.MvcResult;
 
+import javax.servlet.http.Cookie;
+
 @RunWith(SpringRunner.class)
 @SpringBootTest
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
@@ -45,4 +47,15 @@ public class AuthControllerTest extends BaseControllerTest {
         System.out.println(result.getData());
     }
 
+    @Test
+    public void testC_info() throws Exception {
+        Cookie cookie = new Cookie("uid", "4sjrtiHZOu38BaF-9lOyB1jEPXOxBgJ_3jjuugBiDcZs9xlBhPHqdaypVsfMCD42Vnkf8n4lqYvq5UwbButjlIsnvRvw8GWLSh_G4XeYdKCvR9dO6lD3bGUZMIIvck0gAhKf_sazt4Ao3D8eMaLvwyGu0s6-AvNpWa6hRfvwM4WA-rHhu1IugVmtE5FD446qTiXl7A9xbA3q5jIR8Mqj4g8MVV08cV8AYZ0ZQDDiEWgk7tBzsXkkcptG0ZPY-nlEuEgWX8zhzuERmvXea9a7aM4LwX0BNcyJrOFeBz-NI6Tdqo-nw1E__RFznZaAOsHubjeLkyqynezPlXsHpvzanlG9LKqUXUHdZ7TFiKtLyK7ZDr2EcUVejn5UJ2c3cpJZ0_h6242O_E7Ojva4vGDcmbWQ_Q6MbFdG39WDM3kfsYibVgizgUxA45CFO657MQVd03DeE1XfiyZ5ohVN27U7-suyv4JeA_uXkzhEPAQRUkiG5ldUYSF0Q-7y8vPTShgx02Ku5m7IvnMQK87AKx1zalO-WJGw6e1-YbygLbCUdz0QlKUUdPmdfr9QNbnBrO0.");
+        MvcResult mvcResult = mockMvc.perform(get("/info")
+                .cookie(cookie))
+                .andExpect(isSuccess())
+                .andReturn();
+        Result<AuthDTO> result = result(mvcResult, AuthDTO.class);
+        System.out.println("result:========" + result.getData());
+    }
+
 }

+ 3 - 0
base-servers/gateway-server/src/main/resources/application.yml

@@ -186,6 +186,9 @@ auth:
     - /ws/**
     - /api/file/download
     - /api/commons/excel/import/templet
+    - /api/commons/share/**
+    - /api/account/role/list/**
+    - /api/account/account/share/join
   cookie:
     name: uid
     secret-key: 0taQcW073Z7G628g5H

+ 4 - 0
base-servers/sms/sms-api/pom.xml

@@ -38,6 +38,10 @@
             <groupId>io.github.openfeign.form</groupId>
             <artifactId>feign-form-spring</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
     </dependencies>
 
 

+ 2 - 2
base-servers/sms/sms-api/src/main/java/com.usoftchina.saas.sms.api/SmsApi.java → base-servers/sms/sms-api/src/main/java/com/usoftchina/saas/sms/api/SmsApi.java

@@ -13,6 +13,6 @@ public interface SmsApi {
      * 注册成功发送手机短信
      * @param smsDTO
      */
-    @PostMapping(value = "/msg/register")
-    Result sendRegisterMsg(@RequestBody SmsDTO smsDTO);
+    @PostMapping(value = "/msg/send")
+    Result sendMsg(@RequestBody SmsDTO smsDTO);
 }

+ 86 - 0
base-servers/sms/sms-api/src/main/java/com/usoftchina/saas/sms/cache/SmsCache.java

@@ -0,0 +1,86 @@
+package com.usoftchina.saas.sms.cache;
+
+import com.usoftchina.saas.cache.BaseRedisCache;
+import com.usoftchina.saas.context.SpringContextHolder;
+import com.usoftchina.saas.utils.StringUtils;
+import org.springframework.data.redis.core.BoundValueOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
+/**
+ * @Description 短信验证码
+ * @Author chenwei
+ * @Date 2018/12/19
+ */
+public class SmsCache<K, V> extends BaseRedisCache<String, String> {
+
+    private String mobile;
+
+    private static final RedisTemplate<String, String> REDIS_TEMPLATE = SpringContextHolder.getBean("redisTemplate", RedisTemplate.class);
+
+    private SmsCache() {
+        super(() -> REDIS_TEMPLATE);
+    }
+
+    public static SmsCache of(String mobile){
+        SmsCache cache = new SmsCache();
+        cache.mobile = mobile;
+        return cache;
+    }
+
+    @Override
+    protected String key() {
+        return generatePublicKey("sms", this.mobile);
+    }
+    protected BoundValueOperations<String, String> getBoundValueOperations() {
+        RedisTemplate<String, String> redisTemplate = super.getRedisTemplate();
+        redisTemplate.setValueSerializer(new StringRedisSerializer());
+        redisTemplate.setKeySerializer(new StringRedisSerializer());
+        return redisTemplate.boundValueOps(key());
+    }
+
+    @Override
+    public Optional<String> getCache() {
+        String value = this.getBoundValueOperations().get();
+        if (!StringUtils.isEmpty(value)){
+            return Optional.of(value);
+        }
+        return Optional.empty();
+    }
+
+    @Override
+    protected Supplier<String> getSupplier() {
+        return null;
+    }
+
+    @Override
+    public void set(String value) {
+        this.getBoundValueOperations().set(value);
+    }
+
+    @Override
+    public void set(String value, int seconds) {
+        this.getBoundValueOperations().set(value, seconds, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 根据缓存中的key 清除
+     */
+    @Override
+    public void clear() {
+        super.clear();
+    }
+
+    /**
+     * 根据缓存中的key 清除
+     */
+    public void del(String key){
+        this.getRedisTemplate().delete(key);
+    }
+
+}

+ 1 - 1
base-servers/sms/sms-server/src/main/java/com/usoftchina/saas/sms/controller/SmsController.java

@@ -19,7 +19,7 @@ public class SmsController {
     @Autowired
     private SmsService smsService;
 
-    @PostMapping("/msg/register")
+    @PostMapping("/msg/send")
     public Result sendRegisterMsg(@RequestBody SmsDTO smsDTO){
         try {
             smsService.sendMessage(smsConfig, smsDTO);

+ 1 - 1
base-servers/sms/sms-server/src/test/java/com/usoftchina/saas/sms/api/SmsApiTest.java

@@ -36,7 +36,7 @@ public class SmsApiTest {
         JSONObject jsonObject = new JSONObject();
         jsonObject.put("password", password);
         smsDTO.setTemplateParam(jsonObject.toJSONString());
-        Result sendResult = smsApi.sendRegisterMsg(smsDTO);
+        Result sendResult = smsApi.sendMsg(smsDTO);
         System.out.println(sendResult.getCode() + "========" + sendResult.getMessage());
     }
 

+ 48 - 0
base-servers/sms/sms-server/src/test/java/com/usoftchina/saas/sms/cache/SmsCacheTest.java

@@ -0,0 +1,48 @@
+package com.usoftchina.saas.sms.cache;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.Optional;
+
+/**
+ * @Description TODO
+ * @Author chenwei
+ * @Date 2018/12/19
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+public class SmsCacheTest {
+
+    private final String mobile = "18702604854";
+    private final String mobile2 = "18702604709";
+
+    @Test
+    public void testA_set(){
+        SmsCache cache = SmsCache.of(mobile2);
+        cache.set("123456", 60 * 60);
+        Optional<String> optional = cache.getCache();
+        if (optional.isPresent()){
+            System.out.println(optional.toString());
+            System.out.println(mobile2 + "value:\t===========" + optional.get());
+        }else {
+            System.out.println("empty");
+        }
+    }
+
+    @Test
+    public void testB_del(){
+        SmsCache cache = SmsCache.of(mobile);
+        //cache.set("1234");
+        Optional<String> optional = cache.getCache();
+        System.out.println(optional.isPresent());
+        if (optional.isPresent()){
+            System.out.println(mobile + "value:\t===========" + optional.get());
+        }else {
+            System.out.println("empty");
+        }
+    }
+
+}

+ 3 - 1
framework/core/src/main/java/com/usoftchina/saas/exception/ExceptionCode.java

@@ -48,7 +48,9 @@ public enum ExceptionCode implements BaseExceptionCode {
     USER_COMPANY_EXIST(53007, "企业已存在账户"),
     ROLE_HAS_USE(54030, "存在已使用该角色的账户,不允许删除"),
     APPLY_DOING_EXIST(54031, "已存在待处理的加入申请"),
-    HAS_BIND_COMPANY(54032, "已绑定该企业"),
+    HAS_BIND_COMPANY(54032, "已加入企业"),
+    SMS_VALIDCODE_EXPIRE(54033, "短信验证码已过期"),
+    SMS_VALIDCODE_ERROR(54034, "短信验证码错误"),
 
     // 文件相关
     FOLDER_NOT_EXISTS(55000, "文件夹不存在"),

+ 6 - 0
framework/core/src/main/java/com/usoftchina/saas/utils/StringUtils.java

@@ -59,4 +59,10 @@ public abstract class StringUtils extends org.springframework.util.StringUtils{
         value.append(suffix);
         return value.toString();
     }
+
+    public static String createValidCode(int len){
+        int max = (int) Math.pow(10, len) - 1;
+        int min = (int) Math.pow(10, len - 1);
+        return String.valueOf(new Random().nextInt(max) % (max - min + 1) + min);
+    }
 }

+ 1 - 0
frontend/saas-portal-web/static/MP_verify_BMkQAHplMGROBlAn.txt