From da6191fafa9aa07a1f4f56487d23fbc703a935b9 Mon Sep 17 00:00:00 2001
From: zhubaomin <zhubaomin>
Date: 星期三, 11 九月 2024 11:41:47 +0800
Subject: [PATCH] 2024-09-11 朱宝民 新加获取图片验证码接口,完善单点登录接口

---
 pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/CaptchaCtrl.java       |  129 +++++++++
 pipIrr-platform/pipIrr-global/pom.xml                                                                         |    7 
 pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaConfig.java                     |  128 +++++++++
 pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaMathTwoTextCreator.java         |   26 +
 pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/dto/CaptchaDomain.java |   99 +++++++
 pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/CaptchaSV.java         |  104 +++++++
 pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoBa/BaCaptcha.java                         |   56 ++++
 pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/util/CaptchaUtil.java                         |   67 ++++
 pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaCaptchaMapper.xml                                   |   96 ++++++
 pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/LoginVo.java                          |   10 
 pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoCtrl.java                          |   37 ++
 pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoSv.java                            |   14 
 pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaMathOneTextCreator.java         |   25 +
 pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoBa/BaCaptchaMapper.java                    |   36 ++
 14 files changed, 829 insertions(+), 5 deletions(-)

diff --git a/pipIrr-platform/pipIrr-global/pom.xml b/pipIrr-platform/pipIrr-global/pom.xml
index a494f6e..d18263c 100644
--- a/pipIrr-platform/pipIrr-global/pom.xml
+++ b/pipIrr-platform/pipIrr-global/pom.xml
@@ -158,6 +158,13 @@
             <artifactId>commons-codec</artifactId>
             <version>1.15</version>
         </dependency>
+
+        <!-- 鍥剧墖楠岃瘉鐮� -->
+        <dependency>
+            <groupId>com.github.penggle</groupId>
+            <artifactId>kaptcha</artifactId>
+            <version>2.3.2</version>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaConfig.java b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaConfig.java
new file mode 100644
index 0000000..9c2182a
--- /dev/null
+++ b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaConfig.java
@@ -0,0 +1,128 @@
+package com.dy.pipIrrGlobal.config;
+
+import com.google.code.kaptcha.impl.DefaultKaptcha;
+import com.google.code.kaptcha.util.Config;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Properties;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-09-10 11:17
+ * @LastEditTime 2024-09-10 11:17
+ * @Description Google楠岃瘉鐮侀厤缃被锛岄厤缃笁绉嶇被鍨嬬殑楠岃瘉鐮佺敓鎴愬櫒锛氱畝鍗曟枃鏈獙璇佺爜銆佷竴浣嶆暟鍔犲噺涔橀櫎楠岃瘉鐮併�佷袱浣嶆暟鍔犲噺涔橀櫎楠岃瘉鐮�
+ */
+
+@Configuration
+public class KaptchaConfig {
+    private static KaptchaConfig instance;
+
+    /**
+     * 楠岃瘉鐮侀厤缃粯璁ら厤缃�
+     * @return
+     */
+    @Bean(name = "captchaProducer")
+    public DefaultKaptcha getKaptchaBean() {
+        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
+        Properties properties = new Properties();
+        // 鏄惁鏈夎竟妗嗐�傞粯璁rue锛屽彲閫夛細yes锛宯o
+        properties.setProperty("kaptcha.border", "yes");
+        //璁剧疆鍥剧墖杈规棰滆壊
+        properties.setProperty("kaptcha.border.color", "green");
+        // 楠岃瘉鐮佹枃鏈瓧绗﹂鑹层�傞粯璁olor.BLACK
+        properties.setProperty("kaptcha.textproducer.font.color", "black");
+        // 鏂囧瓧闂撮殧
+        properties.put("kaptcha.textproducer.char.space", "10");
+        // 楠岃瘉鐮佸浘鐗囧搴︺�傞粯璁�200
+        properties.setProperty("kaptcha.image.width", "160");
+        // 楠岃瘉鐮佸浘鐗囬珮搴︺�傞粯璁�50
+        properties.setProperty("Kkaptcha.image.height", "60");
+        // 楠岃瘉鐮佹枃鏈瓧绗﹀ぇ灏忋�傞粯璁�40
+        properties.setProperty("kaptcha.textproducer.font.size", "38");
+        // KAPTCHA_SESSION_KEY
+        properties.setProperty("Kkaptcha.session.key", "kaptchaCode");
+        // 楠岃瘉鐮佹枃鏈瓧绗﹂暱搴︺�傞粯璁�5
+        properties.setProperty("kaptcha.textproducer.char.length", "4");
+        // 楠岃瘉鐮佹枃鏈瓧浣撴牱寮忋�傞粯璁わ細new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
+        properties.setProperty("kaptcha.textproducer.font.names", "Arial,Courier");
+        // 骞叉壈瀹炵幇绫�
+        properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise");
+        // 鍥剧墖鏍峰紡銆�
+        // 姘寸汗锛歝om.google.code.kaptcha.impl.WaterRipple
+        // 楸肩溂锛歝om.google.code.kaptcha.impl.FishEyeGimpy
+        // 闃村奖锛歝om.google.code.kaptcha.impl.ShadowGimpy
+        properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.WaterRipple");
+        Config config = new Config(properties);
+        defaultKaptcha.setConfig(config);
+        return defaultKaptcha;
+    }
+
+    /**
+     * 楠岃瘉鐮佹暟瀛﹂绫婚厤缃紙涓�浣嶆暟鍔犲噺涔橀櫎锛�
+     * @return 閰嶇疆淇℃伅
+     */
+    @Bean(name = "captchaProducerMathOne")
+    public DefaultKaptcha getKaptchaBeanMathOne() {
+        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
+        Properties properties = commonConfig("com.dy.pipIrrGlobal.config.KaptchaMathOneTextCreator");
+        Config config = new Config(properties);
+        defaultKaptcha.setConfig(config);
+        return defaultKaptcha;
+    }
+
+    /**
+     * 楠岃瘉鐮佹暟瀛﹂绫婚厤缃紙涓や綅鏁扮殑鍔犲噺涔橀櫎锛�
+     * @return 閰嶇疆淇℃伅
+     */
+    @Bean(name = "captchaProducerMathTwo")
+    public DefaultKaptcha getKaptchaBeanMathTwo() {
+        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
+        Properties properties = commonConfig("com.dy.pipIrrGlobal.config.KaptchaMathTwoTextCreator");
+        Config config = new Config(properties);
+        defaultKaptcha.setConfig(config);
+        return defaultKaptcha;
+    }
+
+    /**
+     * 绠楀紡杩愮畻閰嶇疆鐨勫叕鍏遍厤缃被
+     * @param textImpl 楠岃瘉鐮佹枃鏈敓鎴愬櫒
+     * @return 閰嶇疆绫�
+     */
+    protected static Properties commonConfig(String textImpl) {
+        Properties properties = new Properties();
+        // 鏄惁鏈夎竟妗嗐�傞粯璁や负true锛屽彲璁剧疆锛歽es锛宯o
+        properties.setProperty("kaptcha.border", "yes");
+        // 杈规棰滆壊銆傞粯璁わ細Color.BLACK
+        properties.setProperty("kaptcha.border.color", "105,179,90");
+        // 楠岃瘉鐮佹枃鏈瓧绗﹂鑹层�傞粯璁わ細Color.BLACK
+        properties.setProperty("kaptcha.textproducer.font.color", "blue");
+        // 楠岃瘉鐮佸浘鐗囧搴︺�傞粯璁わ細200
+        properties.setProperty("kaptcha.image.width", "160");
+        // 楠岃瘉鐮佸浘鐗囬珮搴︺�傞粯璁わ細50
+        properties.setProperty("kaptcha.image.height", "60");
+        // 楠岃瘉鐮佹枃鏈瓧绗﹀ぇ灏忋�傞粯璁わ細40
+        properties.setProperty("kaptcha.textproducer.font.size", "35");
+        // KAPTCHA_SESSION_KEY
+        properties.setProperty("kaptcha.session.key", "kaptchaCodeMath");
+        // 楠岃瘉鐮佹枃鏈敓鎴愬櫒
+        properties.setProperty("kaptcha.textproducer.impl", textImpl);
+        // 楠岃瘉鐮佹枃鏈瓧绗﹂棿璺濄�傞粯璁わ細2
+        properties.setProperty("kaptcha.textproducer.char.space", "6");
+        // 楠岃瘉鐮佹枃鏈瓧绗﹂暱搴︺�傞粯璁わ細5
+        properties.setProperty("kaptcha.textproducer.char.length", "6");
+        // 楠岃瘉鐮佹枃鏈瓧浣撴牱寮忋�傞粯璁わ細new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
+        properties.setProperty("kaptcha.textproducer.font.names", "Arial,Courier");
+        // 楠岃瘉鐮佸櫔鐐归鑹层�傞粯璁わ細Color.BLACK
+        properties.setProperty("kaptcha.noise.color", "white");
+        // 骞叉壈瀹炵幇绫�
+        properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise");
+        // 鍥剧墖鏍峰紡銆�
+        // 姘寸汗锛歝om.google.code.kaptcha.impl.WaterRipple
+        // 楸肩溂锛歝om.google.code.kaptcha.impl.FishEyeGimpy
+        // 闃村奖锛歝om.google.code.kaptcha.impl.ShadowGimpy
+        properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.WaterRipple");
+        // 杩斿洖鐢熸垚鐨勯厤缃被
+        return properties;
+    }
+}
diff --git a/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaMathOneTextCreator.java b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaMathOneTextCreator.java
new file mode 100644
index 0000000..f3040b7
--- /dev/null
+++ b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaMathOneTextCreator.java
@@ -0,0 +1,25 @@
+package com.dy.pipIrrGlobal.config;
+
+import com.dy.pipIrrGlobal.util.CaptchaUtil;
+import com.google.code.kaptcha.text.impl.DefaultTextCreator;
+
+import java.security.SecureRandom;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-09-10 10:38
+ * @LastEditTime 2024-09-10 10:38
+ * @Description 楠岃瘉鐮侀殢鏈烘枃鏈敓鎴愬櫒锛氫竴浣嶆暟鐨勫姞鍑忎箻闄�
+ */
+
+public class KaptchaMathOneTextCreator extends DefaultTextCreator {
+    @Override
+    public String getText() {
+        Random random = new SecureRandom();
+        // 鐢熸垚涓や釜闅忔満鏁帮紝闅忔満鏁拌寖鍥达細[0,10)锛屽苟杩斿洖缁撴灉
+        Map<String, String> result = CaptchaUtil.mathTextCreator(random.nextInt(10), random.nextInt(10));
+        return result.get("resultString");
+    }
+}
diff --git a/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaMathTwoTextCreator.java b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaMathTwoTextCreator.java
new file mode 100644
index 0000000..ada8d22
--- /dev/null
+++ b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/KaptchaMathTwoTextCreator.java
@@ -0,0 +1,26 @@
+package com.dy.pipIrrGlobal.config;
+
+import com.dy.pipIrrGlobal.util.CaptchaUtil;
+import com.google.code.kaptcha.text.impl.DefaultTextCreator;
+
+import java.security.SecureRandom;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-09-10 10:39
+ * @LastEditTime 2024-09-10 10:39
+ * @Description 楠岃瘉鐮侀殢鏈烘枃鏈敓鎴愬櫒锛氫袱浣嶆暟鐨勫姞鍑忎箻闄�
+ */
+
+public class KaptchaMathTwoTextCreator extends DefaultTextCreator {
+    @Override
+    public String getText() {
+        Random random = new SecureRandom();
+        // 淇濆瓨璁$畻缁撴灉
+        Map<String, String> result = CaptchaUtil.mathTextCreator(random.nextInt(100), random.nextInt(100));
+        // 鐢熸垚涓や釜闅忔満鏁帮紝闅忔満鏁拌寖鍥达細[0,100)锛屽苟杩斿洖缁撴灉
+        return result.get("resultString");
+    }
+}
diff --git a/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoBa/BaCaptchaMapper.java b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoBa/BaCaptchaMapper.java
new file mode 100644
index 0000000..4c610e3
--- /dev/null
+++ b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoBa/BaCaptchaMapper.java
@@ -0,0 +1,36 @@
+package com.dy.pipIrrGlobal.daoBa;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dy.pipIrrGlobal.pojoBa.BaCaptcha;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.Map;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-09-11 10:58
+ * @LastEditTime 2024-09-11 10:58
+ * @Description
+ */
+
+@Mapper
+public interface BaCaptchaMapper extends BaseMapper {
+    int deleteByPrimaryKey(Long id);
+
+    int insert(BaCaptcha record);
+
+    int insertSelective(BaCaptcha record);
+
+    BaCaptcha selectByPrimaryKey(Long id);
+
+    int updateByPrimaryKeySelective(BaCaptcha record);
+
+    int updateByPrimaryKey(BaCaptcha record);
+
+    /**
+     * 渚濇嵁楠岃瘉鐮乼oken鑾峰彇楠岃瘉瀛楃
+     * @param token
+     * @return
+     */
+    Map getCodeByToken(String token);
+}
\ No newline at end of file
diff --git a/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoBa/BaCaptcha.java b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoBa/BaCaptcha.java
new file mode 100644
index 0000000..28e83d8
--- /dev/null
+++ b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoBa/BaCaptcha.java
@@ -0,0 +1,56 @@
+package com.dy.pipIrrGlobal.pojoBa;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-09-11 10:58
+ * @LastEditTime 2024-09-11 10:58
+ * @Description
+ */
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.alibaba.fastjson2.writer.ObjectWriterImplToString;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.dy.common.po.BaseEntity;
+import jakarta.validation.constraints.NotBlank;
+import lombok.*;
+
+/**
+ * 鍥惧舰楠岃瘉璁板綍琛�
+ */
+
+@TableName(value = "ba_captcha", autoResultMap = true)
+@Data
+@Builder
+@ToString
+@NoArgsConstructor
+@AllArgsConstructor
+public class BaCaptcha implements BaseEntity {
+    public static final long serialVersionUID = 202409111103001L;
+
+    /**
+    * 涓婚敭
+    */
+    @JSONField(serializeUsing = ObjectWriterImplToString.class)
+    @TableId(type = IdType.INPUT)
+    private Long id;
+
+    /**
+    * 楠岃瘉鐮乼oken
+    */
+    @NotBlank(message = "楠岃瘉鐮乼oken涓嶈兘涓虹┖")
+    private String token;
+
+    /**
+    * 楠岃瘉瀛楃
+    */
+    @NotBlank(message = "楠岃瘉瀛楃涓嶈兘涓虹┖")
+    private String code;
+
+    /**
+    * 杩囨湡鏃堕棿
+    */
+    @JSONField(serializeUsing = ObjectWriterImplToString.class)
+    private Long expiration;
+}
\ No newline at end of file
diff --git a/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/util/CaptchaUtil.java b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/util/CaptchaUtil.java
new file mode 100644
index 0000000..5f7bfd8
--- /dev/null
+++ b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/util/CaptchaUtil.java
@@ -0,0 +1,67 @@
+package com.dy.pipIrrGlobal.util;
+
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-09-10 10:32
+ * @LastEditTime 2024-09-10 10:32
+ * @Description 鑷畾涔夐獙璇佺爜宸ュ叿绫�
+ */
+
+public class CaptchaUtil {
+    /**
+     * 鐢熸垚鏁板鏂囨湰绠楀紡锛屼緥濡�1+1=锛�
+     * @param a 鏁板瓧
+     * @param b 鏁板瓧
+     * @return  瀛楃
+     */
+    public static Map<String, String> mathTextCreator(int a, int b) {
+        Random random = new SecureRandom();
+        // 鐢熸垚闅忔満鎿嶄綔锛屾搷浣滆寖鍥达細[0,4)锛屽垎鍒〃绀猴細 +  -  *  /
+        int op = random.nextInt(4);
+        // 瀹氫箟璁$畻鐨勭粨鏋�
+        Integer result = 0;
+        // 瀹氫箟鏋勫缓鐨勭畻寮忓瓧绗︿覆
+        StringBuilder resultString = new StringBuilder();
+        // 杩愮畻绗︼細-
+        if (1 == op) {
+            if (a >= b) {
+                result = a - b;
+                resultString.append(a).append("-").append(b).append("=?@").append(result);
+            } else {
+                result = b - a;
+                resultString.append(b).append("-").append(a).append("=?@").append(result);
+            }
+        }
+        // 杩愮畻绗︼細*
+        else if (2 == op) {
+            result = a * b;
+            resultString.append(a).append("*").append(b).append("=?@").append(result);
+        }
+        // 杩愮畻绗︼細/
+        else if (3 == op) {
+            if (a != 0 && b % a == 0) {
+                result = b / a;
+                resultString.append(b).append("/").append(a).append("=?@").append(result);
+            } else if (b != 0 && a % b == 0) {
+                result = a / b;
+                resultString.append(a).append("/").append(b).append("=?@").append(result);
+            } else {
+                return mathTextCreator(a, b);
+            }
+        }
+        // 杩愮畻绗︼細+
+        else {
+            result = b + a;
+            resultString.append(a).append("+").append(b).append("=?@").append(result);
+        }
+        Map<String, String> ret = new HashMap<String, String>();
+        ret.put("resultCode", result.toString());
+        ret.put("resultString", resultString.toString());
+        return ret;
+    }
+}
diff --git a/pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaCaptchaMapper.xml b/pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaCaptchaMapper.xml
new file mode 100644
index 0000000..f0aeaeb
--- /dev/null
+++ b/pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaCaptchaMapper.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dy.pipIrrGlobal.daoBa.BaCaptchaMapper">
+  <resultMap id="BaseResultMap" type="com.dy.pipIrrGlobal.pojoBa.BaCaptcha">
+    <!--@mbg.generated-->
+    <!--@Table ba_captcha-->
+    <id column="id" jdbcType="BIGINT" property="id" />
+    <result column="token" jdbcType="VARCHAR" property="token" />
+    <result column="code" jdbcType="VARCHAR" property="code" />
+    <result column="expiration" jdbcType="BIGINT" property="expiration" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--@mbg.generated-->
+    id, token, code, expiration
+  </sql>
+  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
+    <!--@mbg.generated-->
+    select 
+    <include refid="Base_Column_List" />
+    from ba_captcha
+    where id = #{id,jdbcType=BIGINT}
+  </select>
+  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
+    <!--@mbg.generated-->
+    delete from ba_captcha
+    where id = #{id,jdbcType=BIGINT}
+  </delete>
+  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoBa.BaCaptcha">
+    <!--@mbg.generated-->
+    insert into ba_captcha (id, token, code, 
+      expiration)
+    values (#{id,jdbcType=BIGINT}, #{token,jdbcType=VARCHAR}, #{code,jdbcType=VARCHAR}, 
+      #{expiration,jdbcType=BIGINT})
+  </insert>
+  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoBa.BaCaptcha">
+    <!--@mbg.generated-->
+    insert into ba_captcha
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        id,
+      </if>
+      <if test="token != null">
+        token,
+      </if>
+      <if test="code != null">
+        code,
+      </if>
+      <if test="expiration != null">
+        expiration,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        #{id,jdbcType=BIGINT},
+      </if>
+      <if test="token != null">
+        #{token,jdbcType=VARCHAR},
+      </if>
+      <if test="code != null">
+        #{code,jdbcType=VARCHAR},
+      </if>
+      <if test="expiration != null">
+        #{expiration,jdbcType=BIGINT},
+      </if>
+    </trim>
+  </insert>
+  <update id="updateByPrimaryKeySelective" parameterType="com.dy.pipIrrGlobal.pojoBa.BaCaptcha">
+    <!--@mbg.generated-->
+    update ba_captcha
+    <set>
+      <if test="token != null">
+        token = #{token,jdbcType=VARCHAR},
+      </if>
+      <if test="code != null">
+        code = #{code,jdbcType=VARCHAR},
+      </if>
+      <if test="expiration != null">
+        expiration = #{expiration,jdbcType=BIGINT},
+      </if>
+    </set>
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoBa.BaCaptcha">
+    <!--@mbg.generated-->
+    update ba_captcha
+    set token = #{token,jdbcType=VARCHAR},
+      code = #{code,jdbcType=VARCHAR},
+      expiration = #{expiration,jdbcType=BIGINT}
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+
+  <!--渚濇嵁楠岃瘉鐮乼oken鑾峰彇楠岃瘉瀛楃-->
+  <select id="getCodeByToken" resultType="java.util.Map">
+    SELECT code, expiration FROM ba_captcha WHERE token = #{token}
+  </select>
+</mapper>
\ No newline at end of file
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/LoginVo.java b/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/LoginVo.java
index cf1501b..57ff5e4 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/LoginVo.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/LoginVo.java
@@ -33,5 +33,15 @@
     @NotEmpty(message = "缁勭粐鍗曚綅涓嶈兘涓虹┖") //涓嶈兘涓虹┖涔熶笉鑳戒负null
     @Length(message = "缁勭粐鍗曚綅鏍囩蹇呴』澶т簬{min}浣�", min = 2)
     public String orgTag ;
+
+    /**
+     * 鍥惧舰楠岃瘉鐮乼oken锛屽嵆session鐨刱ey
+     */
+    private String token;
+
+    /**
+     * 鍥惧舰楠岃瘉鐮佺粨鏋�
+     */
+    private String code;
 }
 
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoCtrl.java b/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoCtrl.java
index 46fc4db..1bbfa52 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoCtrl.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoCtrl.java
@@ -25,9 +25,7 @@
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.List;
-import java.util.Objects;
-import java.util.UUID;
+import java.util.*;
 
 /**
  * 娉ㄨВTag 鍦ˋPI涓樉绀猴細 Tag 娉ㄨВ, 缁欐暣涓帴鍙h捣浜嗕釜鍚嶅瓧涓庢弿杩�"
@@ -45,6 +43,7 @@
     //鍦ㄥ睘鎬т笂娉ㄨВ@Autowired鏃讹紝浼氳鍛� Field injection is not recommended锛堜笉鍐嶆帹鑽愪娇鐢ㄥ瓧娈垫敞鍏ワ級
     private SsoSv sv ;
 
+    //private KaptchaConfig kaptchaConfig;
     //@Autowired
     //private CacheManager cacheManager ;
 
@@ -53,6 +52,10 @@
         this.sv = sv ;
     }
 
+    //@Autowired
+    //public void setKaptchaConfig(KaptchaConfig kaptchaConfig) {
+    //    this.kaptchaConfig = kaptchaConfig;
+    //}
 
     /**
      * 瀹㈡埛绔姹傚緱鍒版墍鏈夌粍缁囨満鏋�
@@ -98,7 +101,7 @@
             )
     })
     @PostMapping(path = "loginJson", consumes = MediaType.APPLICATION_JSON_VALUE)
-    public BaseResponse<UserVo> loginJson(@RequestBody @Parameter(description = "鐧诲綍json鏁版嵁", required = true) @Valid LoginVo vo,  @Parameter(hidden = true) BindingResult bindingResult) {
+    public BaseResponse<UserVo> loginJson(HttpServletRequest request, @RequestBody @Parameter(description = "鐧诲綍json鏁版嵁", required = true) @Valid LoginVo vo,  @Parameter(hidden = true) BindingResult bindingResult) {
         if(bindingResult != null && bindingResult.hasErrors()){
             return BaseResponseUtils.buildErrorMsg(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
         }
@@ -113,6 +116,32 @@
         //鎶婄粍缁囧崟浣嶆爣绛句綔涓烘暟鎹簮鍚嶇О
         DataSourceContext.set(vo.orgTag);
 
+        String token = Optional.ofNullable(vo.getToken()).orElse("");
+        String code = Optional.ofNullable(vo.getCode()).orElse("");
+
+
+
+
+
+        if(token.length() > 0 && code.length() > 0) {
+            // 浠巗ession涓幏鍙栭獙璇佺爜
+            //HttpSession session = (HttpSession) request.getSession();
+            //String localCode = session.getAttribute(token).toString();
+
+            Map map = sv.getCodeByToken(token);
+            Long expiration = Long.parseLong(map.get("expiration").toString());
+            Long currentTimestamp = System.currentTimeMillis();
+            if(currentTimestamp > expiration) {
+                return BaseResponseUtils.buildErrorMsg("楠岃瘉鐮佸凡瓒呮椂");
+            }
+
+            // 浠庢暟鎹簱鑾峰彇楠岃瘉鐮�
+            String localCode = map.get("code").toString();
+            if(!code.equals(localCode)) {
+                return BaseResponseUtils.buildErrorMsg("楠岃瘉鐮侀敊璇�");
+            }
+        }
+
         //寰楀埌鎵�鏈夌敤鎴疯处鍙�
         List<String> phones = sv.getPhones();
         if(!phones.contains(vo.phone)){
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoSv.java b/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoSv.java
index fbd0ceb..bed8576 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoSv.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoSv.java
@@ -1,6 +1,7 @@
 package com.dy.sso.busi;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.dy.pipIrrGlobal.daoBa.BaCaptchaMapper;
 import com.dy.pipIrrGlobal.daoBa.BaUserMapper;
 import com.dy.pipIrrGlobal.pojoBa.BaUser;
 import lombok.extern.slf4j.Slf4j;
@@ -11,11 +12,11 @@
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
+import java.util.Map;
 
 @Slf4j
 @Service
 public class SsoSv {
-
     private BaUserMapper baUserMapper;
 
     @Autowired
@@ -23,6 +24,8 @@
         this.baUserMapper = baUserMapper ;
     }
 
+    @Autowired
+    private BaCaptchaMapper baCaptchaMapper;
 
     /**
      * 闇�瑕丅aUserMapper.xml
@@ -76,4 +79,13 @@
     public List<String> getPhones(){
         return baUserMapper.getPhones() ;
     }
+
+    /**
+     * 渚濇嵁楠岃瘉鐮乼oken鑾峰彇楠岃瘉瀛楃
+     * @param token
+     * @return
+     */
+    public Map getCodeByToken(String token) {
+        return baCaptchaMapper.getCodeByToken(token);
+    }
 }
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/CaptchaCtrl.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/CaptchaCtrl.java
new file mode 100644
index 0000000..933b981
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/CaptchaCtrl.java
@@ -0,0 +1,129 @@
+package com.dy.pipIrrWechat.captcha;
+
+import com.dy.pipIrrGlobal.pojoBa.BaCaptcha;
+import com.dy.pipIrrWechat.captcha.dto.CaptchaDomain;
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.imageio.ImageIO;
+import java.io.IOException;
+import java.util.Calendar;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-09-10 11:40
+ * @LastEditTime 2024-09-10 11:40
+ * @Description 鍥剧墖楠岃瘉鐮�
+ */
+
+@Slf4j
+@RestController
+@RequestMapping(path="captcha")
+public class CaptchaCtrl {
+    @Autowired
+    private CaptchaSV captchaSV;
+
+    /**
+     * 鑾峰彇楠岃瘉鐮�
+     * @param type锛屽浘鐗囩被鍨嬶細char-鏂囨湰锛宮ath-涓�浣嶆暟绠楀紡锛宮ath2-涓や綅鏁扮畻寮�
+     * @return
+     */
+    @GetMapping("/get")
+    @ResponseBody
+    public CaptchaDomain getCaptcha(HttpServletRequest request, @RequestParam(value = "type", required = false, defaultValue = "char") String type) {
+        // 鐢熸垚楠岃瘉鐮佸疄浣�
+        CaptchaDomain captchaDomain = captchaSV.createGoogleCaptcha(type);
+        if (null != captchaDomain) {
+
+            // 楠岃瘉鐮佷繚瀛樿嚦redis
+            // redisUtils.set(captchaDomain.getToken(), captchaDomain.getCode(), 300L);
+
+            // 楠岃瘉鐮佷繚瀛樿嚦session
+            //HttpSession session = (HttpSession) request.getSession();
+            //session.setAttribute(captchaDomain.getToken(), captchaDomain.getCode());
+
+            /**
+             * 楠岃瘉淇濆瓨鍒版暟鎹簱
+             * 鑾峰彇褰撳墠鏃堕棿鎴冲苟寤跺悗3鍒嗛挓
+             */
+            Long timestamp = System.currentTimeMillis();
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTimeInMillis(timestamp);
+            calendar.add(Calendar.SECOND, 180);
+
+            BaCaptcha baCaptcha = new BaCaptcha();
+            baCaptcha.setToken(captchaDomain.getToken());
+            baCaptcha.setCode(captchaDomain.getCode());
+            baCaptcha.setExpiration(calendar.getTimeInMillis());
+            Long rec = captchaSV.addCaptcha(baCaptcha);
+            System.out.println("token: " + captchaDomain.getToken() + "; code: " + captchaDomain.getCode());
+
+            // 鏃犵敤淇℃伅璁剧┖
+            captchaDomain.setText(null);
+            captchaDomain.setCode(null);
+            // 杩斿洖鍓嶇淇℃伅
+            return captchaDomain;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 鐩存帴杈撳嚭鍥剧墖
+     * @param type锛屽浘鐗囩被鍨嬶細char-鏂囨湰锛宮ath-涓�浣嶆暟绠楀紡锛宮ath2-涓や綅鏁扮畻寮�
+     */
+    @GetMapping("/get/image")
+    public void getCaptchaImage(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "type", required = false, defaultValue = "char") String type) {
+        CaptchaDomain captchaDomain = null;
+
+        // 鐢熸垚璋锋瓕楠岃瘉鐮佸疄浣�
+        captchaDomain = captchaSV.createGoogleCaptcha(type);
+
+        // 楠岃瘉鐮佷繚瀛樿嚦redis
+        // redisUtils.set(captchaDomain.getToken(), captchaDomain.getCode(), 300L);
+
+        // 楠岃瘉鐮佷繚瀛樿嚦session
+        //HttpSession session = (HttpSession) request.getSession();
+        //session.setAttribute(captchaDomain.getToken(), captchaDomain.getCode());
+
+        /**
+         * 楠岃瘉淇濆瓨鍒版暟鎹簱
+         * 鑾峰彇褰撳墠鏃堕棿鎴冲苟寤跺悗3鍒嗛挓
+         */
+        Long timestamp = System.currentTimeMillis();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTimeInMillis(timestamp);
+        calendar.add(Calendar.SECOND, 180);
+
+        BaCaptcha baCaptcha = new BaCaptcha();
+        baCaptcha.setToken(captchaDomain.getToken());
+        baCaptcha.setCode(captchaDomain.getCode());
+        baCaptcha.setExpiration(calendar.getTimeInMillis());
+        Long rec = captchaSV.addCaptcha(baCaptcha);
+        System.out.println("token: " + captchaDomain.getToken() + "; code: " + captchaDomain.getCode());
+
+        // 浠ユ枃浠舵祦鐨勫舰寮忥紝杈撳嚭楠岃瘉鐮佸浘鐗�
+        ServletOutputStream out = null;
+        try {
+            response.setContentType("image/jpeg");
+            out = response.getOutputStream();
+            ImageIO.write(captchaDomain.getImage(), "jpg", out);
+            out.flush();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+}
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/CaptchaSV.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/CaptchaSV.java
new file mode 100644
index 0000000..f802662
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/CaptchaSV.java
@@ -0,0 +1,104 @@
+package com.dy.pipIrrWechat.captcha;
+
+import com.dy.pipIrrGlobal.daoBa.BaCaptchaMapper;
+import com.dy.pipIrrGlobal.pojoBa.BaCaptcha;
+import com.dy.pipIrrWechat.captcha.dto.CaptchaDomain;
+import com.google.code.kaptcha.Producer;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.imageio.ImageIO;
+import java.io.ByteArrayOutputStream;
+import java.util.Base64;
+import java.util.UUID;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-09-10 11:40
+ * @LastEditTime 2024-09-10 11:40
+ * @Description
+ */
+
+@Slf4j
+@Service
+public class CaptchaSV {
+    @Autowired
+    private BaCaptchaMapper baCaptchaMapper;
+
+    @Resource(name = "captchaProducer")
+    private Producer captchaProducer;
+
+    @Resource(name = "captchaProducerMathOne")
+    private Producer captchaProducerMathOne;
+
+    @Resource(name = "captchaProducerMathTwo")
+    private Producer captchaProducerMathTwo;
+
+    private static final String TYPE_CHAR = "char";
+    private static final String TYPE_MATH_ONE = "math";
+    private static final String TYPE_MATH_TWO = "math2";
+
+    /**
+     * Kaptcha鐢熸垚楠岃瘉鐮佸疄浣�
+     * @param type锛宑har - 瀛楃(缂虹渷) | math - 涓�浣嶆暟绠楀紡 | math2 - 涓や綅鏁扮畻寮�
+     * @return
+     */
+    public CaptchaDomain createGoogleCaptcha(String type) {
+        // 瀹氫箟楠岃瘉鐮佸疄浣�
+        CaptchaDomain captchaDomain = new CaptchaDomain();
+        // 涓�浣嶆暟鍔犲噺涔橀櫎
+        if (TYPE_MATH_ONE.equals(type)) {
+            // 鐢熸垚鏂囨湰
+            String producerText = captchaProducerMathOne.createText();
+            // 璁剧疆楠岃瘉鐮佸瓧绗�
+            captchaDomain.setText(producerText.substring(0, producerText.indexOf("@")));
+            // 璁剧疆楠岃瘉鐮佺瓟妗堢爜
+            captchaDomain.setCode(producerText.substring(producerText.indexOf("@") + 1));
+            // 璁剧疆楠岃瘉鐮佸浘鐗�
+            captchaDomain.setImage(captchaProducerMathOne.createImage(captchaDomain.getText()));
+        }
+        // 涓や綅鏁板姞鍑忎箻闄�
+        else if (TYPE_MATH_TWO.equals(type)) {
+            String producerText = captchaProducerMathTwo.createText();
+            captchaDomain.setText(producerText.substring(0, producerText.indexOf("@")));
+            captchaDomain.setCode(producerText.substring(producerText.indexOf("@") + 1));
+            captchaDomain.setImage(captchaProducerMathTwo.createImage(captchaDomain.getText()));
+        }
+        // 缂虹渷鎯呭喌锛氬瓧绗�
+        else {
+            captchaDomain.setText(captchaProducer.createText());
+            captchaDomain.setCode(captchaDomain.getText());
+            captchaDomain.setImage(captchaProducer.createImage(captchaDomain.getText()));
+        }
+        // 鐢熸垚base64
+        try {
+            // 瀹氫箟瀛楄妭鏁扮粍杈撳嚭娴�
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            // 灏嗗浘鍍忎互 jpg 鐨勫舰寮忥紝鍐欏埌瀛楄妭鏁扮粍杈撳嚭娴佷腑
+            ImageIO.write(captchaDomain.getImage(), "jpg", outputStream);
+
+            // 鍐欏叆base64鏍煎紡
+            captchaDomain.setBase64("data:image/jpg;base64," + Base64.getEncoder().encodeToString(outputStream.toByteArray()));
+            // 鍐欏叆鍞竴Token
+            captchaDomain.setToken(UUID.randomUUID().toString());
+            // 杩斿洖缁撴灉
+            return captchaDomain;
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * 娣诲姞鍥剧墖楠岃瘉璁板綍
+     * @param po
+     * @return
+     */
+    public Long addCaptcha(BaCaptcha po) {
+        baCaptchaMapper.insert(po);
+        return po.getId();
+    }
+
+}
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/dto/CaptchaDomain.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/dto/CaptchaDomain.java
new file mode 100644
index 0000000..6124205
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/captcha/dto/CaptchaDomain.java
@@ -0,0 +1,99 @@
+package com.dy.pipIrrWechat.captcha.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import java.awt.image.BufferedImage;
+import java.io.Serializable;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-09-10 11:36
+ * @LastEditTime 2024-09-10 11:36
+ * @Description 绗笁鏂归獙璇佺爜瀹炰綋绫�
+ */
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CaptchaDomain implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 楠岃瘉鐮佺殑Token
+     */
+    private String token;
+
+    /**
+     * 楠岃瘉鐮佺殑瀛楃銆傝繑鍥炵殑JSON锛岀姝㈣繑鍥炵粰鍓嶇銆�
+     */
+    @JsonIgnore
+    private String text;
+
+    /**
+     * 楠岃瘉鐮佺殑楠岃瘉瀛楃銆傛瘮濡傜畻寮忕殑缁撴灉绛夈��
+     */
+    @JsonIgnore
+    private String code;
+
+    /**
+     * 楠岃瘉鐮佺紦鍐插浘鍍�
+     */
+    @JsonIgnore
+    private BufferedImage image;
+
+    /**
+     * 楠岃瘉鐮佸浘鐗囩殑Base64瀛楃涓�
+     */
+    private String base64;
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public BufferedImage getImage() {
+        return image;
+    }
+
+    public void setImage(BufferedImage image) {
+        this.image = image;
+    }
+
+    public String getBase64() {
+        return base64;
+    }
+
+    public void setBase64(String base64) {
+        this.base64 = base64;
+    }
+
+    @Override
+    public String toString() {
+        return "CaptchaDomain{" +
+                "token='" + token + '\'' +
+                ", text='" + text + '\'' +
+                ", code='" + code + '\'' +
+                ", image=" + image +
+                ", base64='" + base64 + '\'' +
+                '}';
+    }
+}

--
Gitblit v1.8.0