Kaynağa Gözat

用户身份证识别,营业执照识别完成

Administrator 1 yıl önce
ebeveyn
işleme
0ecdc018b6

+ 4 - 5
pom.xml

@@ -2,8 +2,8 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	
+    <modelVersion>4.0.0</modelVersion>
+
     <groupId>com.ruoyi</groupId>
     <artifactId>ruoyi</artifactId>
     <version>3.8.7</version>
@@ -11,7 +11,7 @@
     <name>ruoyi</name>
     <url>http://www.ruoyi.vip</url>
     <description>若依管理系统</description>
-    
+
     <properties>
         <ruoyi.version>3.8.7</ruoyi.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -27,7 +27,7 @@
         <fastjson.version>2.0.43</fastjson.version>
         <oshi.version>6.5.0</oshi.version>
         <commons.io.version>2.13.0</commons.io.version>
-       <!-- <poi.version>4.1.2</poi.version>-->
+        <!-- <poi.version>4.1.2</poi.version>-->
         <poi.version>5.2.3</poi.version>
         <velocity.version>2.3</velocity.version>
         <jwt.version>0.9.1</jwt.version>
@@ -172,7 +172,6 @@
                 <artifactId>ruoyi-common</artifactId>
                 <version>${ruoyi.version}</version>
             </dependency>
-
         </dependencies>
     </dependencyManagement>
 

+ 19 - 20
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/OcrController.java

@@ -1,21 +1,15 @@
 package com.ruoyi.web.controller.common;
 
-import com.alibaba.fastjson2.JSONObject;
+
 import com.ruoyi.common.annotation.RepeatSubmit;
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.common.core.domain.entity.SysUser;
-import com.ruoyi.common.core.domain.model.LoginBody;
+import com.ruoyi.common.core.domain.IdCardVo;
 import com.ruoyi.common.utils.IdCardUtil;
-import com.ruoyi.common.utils.SendSmsUtils;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-import java.util.concurrent.TimeUnit;
-
-import static com.ruoyi.common.constant.CommonConstants.LOGIN_USER_SMS;
-
 /**
  * @Author: tjf
  * @Date: 2024/4/22 14:24
@@ -26,29 +20,34 @@ import static com.ruoyi.common.constant.CommonConstants.LOGIN_USER_SMS;
 public class OcrController {
     /**
      * 身份证识别
+     *
      * @return
      */
     @PostMapping("/ocrIdCard")
     @RepeatSubmit(interval = 1000, message = "请求过于频繁")
-    public AjaxResult ocrIdCard(String image) {
-        JSONObject jsonObject = IdCardUtil.idCard(image);
-        if (image != null){
-            return  AjaxResult.success(jsonObject);
-        }
-        return AjaxResult.error("图片为空");
+    public AjaxResult ocrIdCard(@RequestBody IdCardVo idCardVo) {
+        return IdCardUtil.idCard(idCardVo.getImage(),idCardVo.getIdCardSide());
     }
 
     /**
      * 营业执照识别
+     *
      * @return
      */
     @PostMapping("/ocrBusinessLicense")
     @RepeatSubmit(interval = 1000, message = "请求过于频繁")
-    public AjaxResult ocrBusinessLicense(String image) {
-        JSONObject jsonObject = IdCardUtil.businessLicense(image);
-        if (image != null){
-            return  AjaxResult.success(jsonObject);
-        }
-        return AjaxResult.error("图片为空");
+    public AjaxResult ocrBusinessLicense(@RequestBody IdCardVo idCardVo) {
+        return IdCardUtil.businessLicense(idCardVo.getImage());
+    }
+
+    /**
+     * 人脸识别百度V4版本
+     *
+     * @return
+     */
+    @PostMapping("/ocrSample")
+    @RepeatSubmit(interval = 1000, message = "请求过于频繁")
+    public AjaxResult ocrSample(@RequestBody IdCardVo idCardVo) {
+        return IdCardUtil.sample(idCardVo);
     }
 }

+ 18 - 9
ruoyi-common/pom.xml

@@ -15,13 +15,19 @@
         common通用工具
     </description>
 
+
     <dependencies>
 
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.27</version>
+        </dependency>
         <!--阿里短信服务-->
         <dependency>
             <groupId>com.aliyun</groupId>
             <artifactId>dysmsapi20170525</artifactId>
-            <version>2.0.23</version>
+            <version>2.0.24</version>
         </dependency>
 
         <!-- Spring框架基本的核心工具 -->
@@ -59,19 +65,19 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
-  
+
         <!-- JSON工具类 -->
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
         </dependency>
-        
+
         <!-- 动态数据源 -->
-		<dependency>
-			<groupId>com.baomidou</groupId>
-			<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
-			<version>3.5.2</version>
-		</dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
+            <version>3.5.2</version>
+        </dependency>
 
         <!-- 阿里JSON解析器 -->
         <dependency>
@@ -138,7 +144,10 @@
             <artifactId>poi-tl</artifactId>
             <version>1.12.2</version>
         </dependency>
-
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 6 - 0
ruoyi-common/src/main/java/com/ruoyi/common/constant/CommonConstants.java

@@ -21,6 +21,8 @@ public class CommonConstants {
     public static final String TWE = "12";
     public static final String YES = "是";
     public static final String NO = "否";
+    public static final String FRONT = "front";
+    public static final String BACK = "back";
 
     //角色权限
     //超级管理员
@@ -36,5 +38,9 @@ public class CommonConstants {
      * 密码加密16位秘钥
      */
     public static final String LOGIN_PASSWORD_AES = "qwertyuiopasdfgh";
+    /**
+     * 百度ACCESS_TOKEN
+     */
+    public static final String BAI_DU_ACCESS_TOKEN = "BAI_DU_ACCESS_TOKEN:";
 
 }

+ 71 - 0
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/IdCardVo.java

@@ -0,0 +1,71 @@
+package com.ruoyi.common.core.domain;
+
+import java.io.Serializable;
+
+/**
+ * @Author: tjf
+ * @Date: 2024/4/23 14:58
+ * @Describe:
+ */
+public class IdCardVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * 身份证号码
+     */
+    private String idCard;
+    /**
+     * 姓名
+     */
+    private String name;
+    /**
+     * 图片
+     */
+    private String image;
+    /**
+     *-front:身份证含照片的一面
+     * -back:身份证带国徽的一面
+     */
+    private String idCardSide;
+
+    public String getIdCardSide() {
+        return idCardSide;
+    }
+
+    public void setIdCardSide(String idCardSide) {
+        this.idCardSide = idCardSide;
+    }
+
+    public String getIdCard() {
+        return idCard;
+    }
+
+    public void setIdCard(String idCard) {
+        this.idCard = idCard;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getImage() {
+        return image;
+    }
+
+    public void setImage(String image) {
+        this.image = image;
+    }
+
+    @Override
+    public String toString() {
+        return "IdCardVo{" +
+                "idCard='" + idCard + '\'' +
+                ", name='" + name + '\'' +
+                ", image='" + image + '\'' +
+                ", idCardSide='" + idCardSide + '\'' +
+                '}';
+    }
+}

+ 4 - 4
ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtil.java → ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtils.java

@@ -11,12 +11,12 @@ import java.util.Map;
 /**
  * http 工具类
  */
-public class HttpUtil {
+public class HttpUtils {
 
     public static String post(String requestUrl, String accessToken, String params)
             throws Exception {
         String contentType = "application/x-www-form-urlencoded";
-        return HttpUtil.post(requestUrl, accessToken, contentType, params);
+        return HttpUtils.post(requestUrl, accessToken, contentType, params);
     }
 
     public static String post(String requestUrl, String accessToken, String contentType, String params)
@@ -25,13 +25,13 @@ public class HttpUtil {
         if (requestUrl.contains("nlp")) {
             encoding = "GBK";
         }
-        return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding);
+        return HttpUtils.post(requestUrl, accessToken, contentType, params, encoding);
     }
 
     public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding)
             throws Exception {
         String url = requestUrl + "?access_token=" + accessToken;
-        return HttpUtil.postGeneralUrl(url, contentType, params, encoding);
+        return HttpUtils.postGeneralUrl(url, contentType, params, encoding);
     }
 
     public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding)

+ 185 - 97
ruoyi-common/src/main/java/com/ruoyi/common/utils/IdCardUtil.java

@@ -6,21 +6,30 @@ package com.ruoyi.common.utils;
  * @Describe:
  */
 
+import cn.hutool.http.HttpUtil;
+import com.ruoyi.common.core.redis.RedisCache;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
-import com.ruoyi.common.utils.FileUtil;
-import com.ruoyi.common.utils.HttpUtil;
-import okhttp3.*;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.domain.IdCardVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 
 import javax.crypto.Cipher;
 import javax.crypto.spec.SecretKeySpec;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.Base64;
+import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
-public class IdCardUtil {
+import static com.ruoyi.common.constant.CommonConstants.*;
 
+public class IdCardUtil {
     /**
      * 重要提示代码中所需工具类
      * FileUtil,HttpUtil请从
@@ -31,11 +40,8 @@ public class IdCardUtil {
      * https://cloud.baidu.com/doc/OCR/s/rk3h7xzck 文档地址
      */
 
-    // 请求url
-    static String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
-
-    // aes key 从console控制台获取
-    static String aesKey = "[16位 aeskey]";
+    // aes key 从console控制台获取 身份证识别使用
+    static String aesKey = "ce539dc069ad0908";
 
     static byte[] originAesKey = null;
 
@@ -117,46 +123,47 @@ public class IdCardUtil {
      * },
      * "words_result_num": 6
      * }
+     * <p>
+     * <p>
+     * {
+     * "words_result": {
+     * "失效日期": {
+     * "words": "20390711",
+     * "location": {
+     * "top": 445,
+     * "left": 523,
+     * "width": 153,
+     * "height": 38
+     * }
+     * },
+     * "签发机关": {
+     * "words": "陆丰市公安局",
+     * "location": {
+     * "top": 377,
+     * "left": 339,
+     * "width": 195,
+     * "height": 38
+     * }
+     * },
+     * "签发日期": {
+     * "words": "20190606",
+     * "location": {
+     * "top": 445,
+     * "left": 343,
+     * "width": 152,
+     * "height": 38
+     * }
+     * }
+     * },
+     * "log_id": "1559208562721579328",
+     * "words_result_num": 3,
+     * "error_code": 0,
+     * "image_status": "normal"
+     * }
      *
-     *
-     {
-     "words_result": {
-     "失效日期": {
-     "words": "20390711",
-     "location": {
-     "top": 445,
-     "left": 523,
-     "width": 153,
-     "height": 38
-     }
-     },
-     "签发机关": {
-     "words": "陆丰市公安局",
-     "location": {
-     "top": 377,
-     "left": 339,
-     "width": 195,
-     "height": 38
-     }
-     },
-     "签发日期": {
-     "words": "20190606",
-     "location": {
-     "top": 445,
-     "left": 343,
-     "width": 152,
-     "height": 38
-     }
-     }
-     },
-     "log_id": "1559208562721579328",
-     "words_result_num": 3,
-     "error_code": 0,
-     "image_status": "normal"
-     }
      * @return
      */
-    public static JSONObject idCard(String image) {
+    public static AjaxResult idCard(String image, String idCardSide) {
         try {
             // 文件路径
             byte[] imgData = FileUtil.readFileByBytes(image);
@@ -164,22 +171,38 @@ public class IdCardUtil {
             String imgStr = encryptImg(aesKey, imgData);
 
             String imgParam = URLEncoder.encode(imgStr, "UTF-8");
-
-            String param = "id_card_side=" + "front" +
+            String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
+            //-front:身份证含照片的一面
+            //-back:身份证带国徽的一面
+            //自动检测身份证正反面,如果传参指定方向与图片相反,支持正常识别,返回参数image_status字段为"reversed_side"
+            String param = "id_card_side=" + idCardSide +
                     "&image=" + imgParam +
                     "&AESEncry=" + true;
-
-            String accessToken = getAccessToken();
-
-            String encryptResult = HttpUtil.post(url, accessToken, param);
-
+            String accessToken = getAccessToken("TvvuZOOh7MgnlDFnw11ln67n", "CY47OI0eKAzYBD2LO55SM3OITzsyq6DK");
+            String encryptResult = HttpUtils.post(url, accessToken, param);
             String decryptResult = parseResult(encryptResult);
             JSONObject jsonObject = JSON.parseObject(decryptResult);
-            return jsonObject;
+            String wordsResult = jsonObject.getString("words_result");
+            Map<String,Object> map = new HashMap<>(3);
+            if (StringUtils.isNotEmpty(wordsResult)){
+                JSONObject jsonObjectWordsResult = JSON.parseObject(wordsResult);
+                if (FRONT.equals(idCardSide)){
+                    String name = JSON.parseObject(jsonObjectWordsResult.getString("姓名")).getString("words");
+                    String address = JSON.parseObject(jsonObjectWordsResult.getString("住址")).getString("words");
+                    String idCard = JSON.parseObject(jsonObjectWordsResult.getString("公民身份号码")).getString("words");
+                    map.put("realName",name);
+                    map.put("address",address);
+                    map.put("idCard",idCard);
+                }else if (BACK.equals(idCardSide)){
+                    String date = JSON.parseObject(jsonObjectWordsResult.getString("失效日期")).getString("words");
+                    map.put("expirationDate",date);
+                }
+            }
+            return AjaxResult.success(map);
         } catch (Exception e) {
             e.printStackTrace();
         }
-        return null;
+        return AjaxResult.error();
     }
 
     /**
@@ -320,9 +343,6 @@ public class IdCardUtil {
         }
     }
 
-
-    static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();
-
     /**
      * 营业执照识别
      * 重要提示代码中所需工具类
@@ -333,7 +353,7 @@ public class IdCardUtil {
      * https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
      * 下载
      */
-    public static JSONObject businessLicense(String image) {
+    public static AjaxResult businessLicense(String image) {
         // 请求url
         String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/business_license";
         try {
@@ -341,13 +361,9 @@ public class IdCardUtil {
             byte[] imgData = FileUtil.readFileByBytes(image);
             String imgStr = com.ruoyi.common.utils.Base64Util.encode(imgData);
             String imgParam = URLEncoder.encode(imgStr, "UTF-8");
-
             String param = "image=" + imgParam;
-
-            // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
-            String accessToken = IdCardUtil.getAccessToken();
-
-            String result = HttpUtil.post(url, accessToken, param);
+            String accessToken = getAccessToken("TvvuZOOh7MgnlDFnw11ln67n", "CY47OI0eKAzYBD2LO55SM3OITzsyq6DK");
+            String result = HttpUtils.post(url, accessToken, param);
             /**
              *
              {
@@ -503,51 +519,123 @@ public class IdCardUtil {
              }
              */
             JSONObject jsonObject = JSONObject.parseObject(result);
-            return jsonObject;
+            String wordsResult = jsonObject.getString("words_result");
+            Map<String,Object> map = new HashMap<>(8);
+            if (StringUtils.isNotEmpty(wordsResult)){
+                JSONObject jsonObjectWordsResult = JSON.parseObject(wordsResult);
+                String creditCode = JSON.parseObject(jsonObjectWordsResult.getString("社会信用代码")).getString("words");
+                String enterpriseName = JSON.parseObject(jsonObjectWordsResult.getString("单位名称")).getString("words");
+                String enterpriseType = JSON.parseObject(jsonObjectWordsResult.getString("类型")).getString("words");
+                String enterpriseAddress = JSON.parseObject(jsonObjectWordsResult.getString("地址")).getString("words");
+                String legalName = JSON.parseObject(jsonObjectWordsResult.getString("法人")).getString("words");
+                String registeredCapital = JSON.parseObject(jsonObjectWordsResult.getString("注册资本")).getString("words");
+                String establishData = JSON.parseObject(jsonObjectWordsResult.getString("成立日期")).getString("words");
+                String businessTerm = JSON.parseObject(jsonObjectWordsResult.getString("有效期")).getString("words");
+                map.put("creditCode",creditCode);
+                map.put("enterpriseName",enterpriseName);
+                map.put("enterpriseType",enterpriseType);
+                map.put("enterpriseAddress",enterpriseAddress);
+                map.put("legalName",legalName);
+                map.put("registeredCapital",registeredCapital);
+                map.put("establishData",establishData);
+                map.put("businessTerm",businessTerm);
+            }
+            return AjaxResult.success(map);
         } catch (Exception e) {
             e.printStackTrace();
         }
-        return null;
+        return AjaxResult.error();
     }
+
     /**
-     * 获取百度开放平台的AccessToken
-     * @return
+     * 人脸识别
+     *
+     * @throws IOException
      */
-    public static String getAccessToken() {
-        MediaType mediaType = MediaType.parse("application/json");
-        RequestBody body = RequestBody.create(mediaType, "");
-        String url = "https://aip.baidubce.com/oauth/2.0/token";
+    public static AjaxResult sample(IdCardVo idCardVo) {
+        String image = idCardVo.getImage();
+        String idCardNumber = idCardVo.getIdCard();
+        String name = idCardVo.getName();
+        if (StringUtils.isEmpty(image) || StringUtils.isEmpty(idCardNumber) || StringUtils.isEmpty(name)) {
+            return AjaxResult.error("参数不完整");
+        }
+        // image 可以通过 getFileContentAsBase64("C:\fakepath\1675840208844.png") 方法获取,如果Content-Type是application/x-www-form-urlencoded时,第二个参数传true
+        HashMap<String, Object> paramMap = new HashMap<>();
+        paramMap.put("access_token", getAccessToken("OmTDmo9hv4wll1ReYiRNJEfz", "vqnio9p7C17nbrkVar0MrHU4KOz2OXOr"));
+        paramMap.put("image", getFileContentAsBase64(image, false));
+        paramMap.put("image_type", "BASE64");
+        paramMap.put("id_card_number", idCardNumber);
+        paramMap.put("name", name);
+        paramMap.put("spoofing_control", "NORMAL");
+        paramMap.put("quality_control", "NORMAL");
+        //返回值
+        String post = HttpUtil.post("https://aip.baidubce.com/rest/2.0/face/v4/mingjing/verify", paramMap);
         /**
-         * grant_type: 必须参数,固定为client_credentials;
-         * client_id: 必须参数,应用的API Key;
-         * client_secret: 必须参数,应用的Secret Key;
+         * {
+         *     "log_id": 1370579072568000512,
+         *     "result": {
+         *         "score": 40.884,
+         *         "verify_status": 0
+         *     },
+         *     "dec_image": "/9j/4AAQSkZJRgABAgAAAQABAAD",
+         *     "risk_level": "3",
+         *     "risk_tag": [
+         *         "若判断为有风险,则会有风险标签json 数组告知风险类型,如:general_inject"
+         *     ]
+         * }
          */
-        String grantType = "client_credentials";
-        String clientId = "11111111111111";
-        String clientSecret = "22222222222222222";
-        String apiUrl = String.format("%s?grant_type=%s&client_id=%s&client_secret=%s",
-                url, grantType, clientId, clientSecret);
-
-        Request request = new Request.Builder()
-                .url(apiUrl)
-                .method("POST", body)
-                .addHeader("Content-Type", "application/json")
-                .addHeader("Accept", "application/json")
-                .build();
-        Response response = null;
+        JSONObject jsonObject = JSONObject.parseObject(post);
+        Map<String, Object> map = new HashMap<>();
+        return AjaxResult.success(map);
+    }
+
+    /**
+     * 获取文件base64编码
+     *
+     * @param path      文件路径
+     * @param urlEncode 如果Content-Type是application/x-www-form-urlencoded时,传true
+     * @return base64编码信息,不带文件头
+     * @throws IOException IO异常
+     */
+    static String getFileContentAsBase64(String path, boolean urlEncode) {
+        byte[] b = new byte[0];
         try {
-            response = HTTP_CLIENT.newCall(request).execute();
+            b = Files.readAllBytes(Paths.get(path));
         } catch (IOException e) {
             e.printStackTrace();
         }
-        //todo 判断是否成功调用
-        //取出返回的access_token
-        JSONObject jsonObject = null;
-        String accessToken = null;
-        if (response != null) {
-            jsonObject = JSON.parseObject(response.toString());
-            accessToken = jsonObject.getString("access_token");
+        String base64 = Base64.getEncoder().encodeToString(b);
+        if (urlEncode) {
+            try {
+                base64 = URLEncoder.encode(base64, "utf-8");
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+            }
         }
+        return base64;
+    }
+
+    /**
+     * 获取百度开放平台的AccessToken
+     * client_id: 必须参数,应用的API Key;
+     * client_secret: 必须参数,应用的Secret Key;不同的功能不同
+     *
+     * @return
+     */
+    public static String getAccessToken(String apiKey, String secretKey) {
+        String url = "https://aip.baidubce.com/oauth/2.0/token";
+        /**
+         *grant_type: 必须参数,固定为client_credentials;
+         *client_id: 必须参数,应用的API Key;
+         *client_secret: 必须参数,应用的Secret Key;
+         */
+        HashMap<String, Object> paramMap = new HashMap<>(3);
+        paramMap.put("grant_type", "client_credentials");
+        paramMap.put("client_id", apiKey);
+        paramMap.put("client_secret", secretKey);
+        String post = cn.hutool.http.HttpUtil.post(url, paramMap);
+        JSONObject jsonObject = JSONObject.parseObject(post);
+        String accessToken = jsonObject.getString("access_token");
         return accessToken;
     }
 }

+ 27 - 26
ruoyi-common/src/main/java/com/ruoyi/common/utils/SendSmsUtils.java

@@ -5,7 +5,6 @@ import com.aliyun.dysmsapi20170525.models.SendBatchSmsRequest;
 import com.aliyun.dysmsapi20170525.models.SendBatchSmsResponse;
 import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
 import com.aliyun.tea.TeaException;
-import com.aliyun.teautil.models.RuntimeOptions;
 
 /**
  * @author tjf
@@ -39,12 +38,14 @@ public class SendSmsUtils {
      * @throws Exception
      */
     public static com.aliyun.dysmsapi20170525.Client createClient() throws Exception {
+        // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
+        // 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
         com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
-            // 必填,您的 AccessKey ID
-            .setAccessKeyId(ACCESS_KEY_ID)
-            // 必填,您的 AccessKey Secret
-            .setAccessKeySecret(ACCESS_KEY_SECRET);
-        // 访问的域名
+                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
+                .setAccessKeyId(System.getenv(ACCESS_KEY_ID))
+                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
+                .setAccessKeySecret(System.getenv(ACCESS_KEY_SECRET));
+        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
         config.endpoint = "dysmsapi.aliyuncs.com";
         return new com.aliyun.dysmsapi20170525.Client(config);
     }
@@ -62,16 +63,16 @@ public class SendSmsUtils {
             com.aliyun.dysmsapi20170525.Client client = SendSmsUtils.createClient();
 
             com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
-                //手机号码
-                .setPhoneNumbers(phone)
-                //短信签名名称。中新云
-                .setSignName("中新云")
-                //短信模板变量对应的实际值{"name": code}
-                .setTemplateParam(smsCode)
-                //短信模板CODE
-                .setTemplateCode(templateCode);
+                    //手机号码
+                    .setPhoneNumbers(phone)
+                    //短信签名名称。中新云
+                    .setSignName("中新云")
+                    //短信模板变量对应的实际值{"name": code}
+                    .setTemplateParam(smsCode)
+                    //短信模板CODE
+                    .setTemplateCode(templateCode);
             // 复制代码运行请自行打印 API 的返回值
-            SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());
+            SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new com.aliyun.teautil.models.RuntimeOptions());
             code = sendSmsResponse.getBody().code;
         } catch (Exception _error) {
         }
@@ -84,10 +85,10 @@ public class SendSmsUtils {
      * @return
      * @throws
      */
-    public static SendBatchSmsResponse sendBatchSms(SendBatchSmsRequest sendBatchSmsRequest){
+    public static SendBatchSmsResponse sendBatchSms(SendBatchSmsRequest sendBatchSmsRequest) {
         try {
             com.aliyun.dysmsapi20170525.Client client = SendSmsUtils.createClient();
-            RuntimeOptions runtime = new RuntimeOptions();
+            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
             SendBatchSmsResponse sendBatchSmsResponse = client.sendBatchSmsWithOptions(sendBatchSmsRequest, runtime);
             return sendBatchSmsResponse;
             // 复制代码运行请自行打印 API 的返回值
@@ -113,16 +114,16 @@ public class SendSmsUtils {
             com.aliyun.dysmsapi20170525.Client client = SendSmsUtils.createClient();
             String smsCode = "{\"code\":\"" + code + "\"}";
             com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
-                //手机号码
-                .setPhoneNumbers(phone)
-                //短信签名名称。潜山市数据资源局
-                .setSignName("潜山市政协办公室")
-                //短信模板CODE
-                .setTemplateCode("SMS_219525380")
-                //短信模板变量对应的实际值{"name": code}
-                .setTemplateParam(smsCode);
+                    //手机号码
+                    .setPhoneNumbers(phone)
+                    //短信签名名称。潜山市数据资源局
+                    .setSignName("潜山市政协办公室")
+                    //短信模板CODE
+                    .setTemplateCode("SMS_219525380")
+                    //短信模板变量对应的实际值{"name": code}
+                    .setTemplateParam(smsCode);
             // 复制代码运行请自行打印 API 的返回值
-            SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());
+            SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new com.aliyun.teautil.models.RuntimeOptions());
             code = sendSmsResponse.getBody().code;
         } catch (Exception _error) {
         }

+ 1 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java

@@ -113,6 +113,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .authorizeRequests()
                 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
                 .antMatchers("/login", "/register", "/captchaImage").permitAll()
+                .antMatchers("/ocr/**").permitAll()
                 // 静态资源,可匿名访问
                 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                 .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()