Administrator
2024-02-26 b5b296cc01699f96029b07073fe9d0078bedd445
2024-02-26 朱宝民 解决添加用户主键不自动创建的问题,部分微信支付代码
4个文件已修改
13个文件已添加
1335 ■■■■■ 已修改文件
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mybatis/AutoGenerateIdInterceptor.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoSe/SeWebchatLogonStateMapper.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoSe/SeWebchatLogonState.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeWebchatLogonStateMapper.xml 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/pom.xml 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/PipIrrWebChatApplication.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/config/RestTemplateConfig.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/config/RestTemplateWechatCertConfig.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/payment/PayHelper.java 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/payment/PayInfo.java 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/payment/PaymentCtrl.java 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/payment/PaymentSv.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/payment/dto/Code2Session.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/util/ICallback.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/util/OkHttpUtil.java 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/util/RestTemplateUtil.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/resources/application.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mybatis/AutoGenerateIdInterceptor.java
@@ -1,16 +1,14 @@
package com.dy.common.mybatis;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.dy.common.po.BaseEntity;
import com.dy.common.util.IDLongGenerator;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.plugin.*;
import java.lang.reflect.Method;
@@ -28,6 +26,7 @@
    static int MAPPED_STATEMENT_INDEX = 0;
    static int PARAMETER_INDEX = 1;
    static String BASE_FIELD_SET_PRIMARY_KEY_FUNTION_NAME = "setId";
    static String BASE_FIELD_SET_PRIMARY_KEY_FUNTION_NAME2 = "setUserId";
    /**
     * 拦截逻辑实现
@@ -45,8 +44,15 @@
                Class<?> entityClass = entity.getClass();
                Method setMt = null ;
                try{
                    // 判断主键是id还是userId
                    String jsonString = JSONObject.toJSONString(entity, JSONWriter.Feature.WriteMapNullValue);
                    JSONObject jsonObject = JSONObject.parseObject(jsonString);
                    if(jsonObject.containsKey("userId")) {
                        setMt = entityClass.getMethod(BASE_FIELD_SET_PRIMARY_KEY_FUNTION_NAME2, Long.class) ;
                    }else {
                    //有一些实体没有id,例如中间表
                    setMt = entityClass.getMethod(BASE_FIELD_SET_PRIMARY_KEY_FUNTION_NAME, Long.class) ;
                    }
                }catch (Exception e){
                    //当entityClass没有setId方法时,会抛出异常
                }
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoSe/SeWebchatLogonStateMapper.java
New file
@@ -0,0 +1,27 @@
package com.dy.pipIrrGlobal.daoSe;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dy.pipIrrGlobal.pojoSe.SeWebchatLogonState;
import org.apache.ibatis.annotations.Mapper;
/**
 * @author ZhuBaoMin
 * @date 2024-02-22 17:31
 * @LastEditTime 2024-02-22 17:31
 * @Description
 */
@Mapper
public interface SeWebchatLogonStateMapper extends BaseMapper<SeWebchatLogonState> {
    int deleteByPrimaryKey(Long id);
    int insert(SeWebchatLogonState record);
    int insertSelective(SeWebchatLogonState record);
    SeWebchatLogonState selectByPrimaryKey(Long id);
    int updateByPrimaryKeySelective(SeWebchatLogonState record);
    int updateByPrimaryKey(SeWebchatLogonState record);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoSe/SeWebchatLogonState.java
New file
@@ -0,0 +1,60 @@
package com.dy.pipIrrGlobal.pojoSe;
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 io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.*;
import java.util.Date;
/**
 * @author ZhuBaoMin
 * @date 2024-02-22 17:31
 * @LastEditTime 2024-02-22 17:31
 * @Description
 */
@TableName(value="se_webchat_logon_state", autoResultMap = true)
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "登录态记录实体")
public class SeWebchatLogonState implements BaseEntity {
    public static final long serialVersionUID = 202402221735001L;
    /**
    * 主键
    */
    @JSONField(serializeUsing= ObjectWriterImplToString.class)
    @TableId(type = IdType.INPUT)
    @Schema(description = "实体id", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private Long id;
    /**
    * 用户唯一标识
    */
    @Schema(description = "用户唯一标识", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotBlank(message = "用户唯一标识不能为空")
    private String openId;
    /**
    * 会话密钥
    */
    @Schema(description = "会话密钥", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotBlank(message = "会话密钥不能为空")
    private String sessionKey;
    /**
    * 创建时间
    */
    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotBlank(message = "创建时间不能为空")
    private Date createTime;
}
pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeWebchatLogonStateMapper.xml
New file
@@ -0,0 +1,91 @@
<?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.daoSe.SeWebchatLogonStateMapper">
  <resultMap id="BaseResultMap" type="com.dy.pipIrrGlobal.pojoSe.SeWebchatLogonState">
    <!--@mbg.generated-->
    <!--@Table se_webchat_logon_state-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="open_id" jdbcType="VARCHAR" property="openId" />
    <result column="session_key" jdbcType="VARCHAR" property="sessionKey" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, open_id, session_key, create_time
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from se_webchat_logon_state
    where id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    <!--@mbg.generated-->
    delete from se_webchat_logon_state
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoSe.SeWebchatLogonState">
    <!--@mbg.generated-->
    insert into se_webchat_logon_state (id, open_id, session_key,
      create_time)
    values (#{id,jdbcType=BIGINT}, #{openId,jdbcType=VARCHAR}, #{sessionKey,jdbcType=VARCHAR},
      #{createTime,jdbcType=TIMESTAMP})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoSe.SeWebchatLogonState">
    <!--@mbg.generated-->
    insert into se_webchat_logon_state
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="openId != null">
        open_id,
      </if>
      <if test="sessionKey != null">
        session_key,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="openId != null">
        #{openId,jdbcType=VARCHAR},
      </if>
      <if test="sessionKey != null">
        #{sessionKey,jdbcType=VARCHAR},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.dy.pipIrrGlobal.pojoSe.SeWebchatLogonState">
    <!--@mbg.generated-->
    update se_webchat_logon_state
    <set>
      <if test="openId != null">
        open_id = #{openId,jdbcType=VARCHAR},
      </if>
      <if test="sessionKey != null">
        session_key = #{sessionKey,jdbcType=VARCHAR},
      </if>
      <if test="createTime != null">
        create_time = #{createTime,jdbcType=TIMESTAMP},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoSe.SeWebchatLogonState">
    <!--@mbg.generated-->
    update se_webchat_logon_state
    set open_id = #{openId,jdbcType=VARCHAR},
      session_key = #{sessionKey,jdbcType=VARCHAR},
      create_time = #{createTime,jdbcType=TIMESTAMP}
    where id = #{id,jdbcType=BIGINT}
  </update>
</mapper>
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/pom.xml
@@ -16,6 +16,39 @@
    <name>pipIrr-web-webchat</name>
    <description>web微信支付模块</description>
    <dependencies>
        <!--微信支付-->
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-java</artifactId>
            <version>0.2.12</version>
        </dependency>
        <!--OkHttp-->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.9.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents.client5</groupId>
            <artifactId>httpclient5</artifactId>
            <version>5.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents.client5</groupId>
            <artifactId>httpclient5-fluent</artifactId>
            <version>5.1.3</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- 生成不包含依赖jar的可执行jar包
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/PipIrrWebChatApplication.java
@@ -18,7 +18,7 @@
@EnableAspectJAutoProxy
@EnableMultiDataSource
@ComponentScan(basePackages = {"com.dy.common", "com.dy.pipIrrGlobal", "com.dy.pipirrWebChat"})
@MapperScan({"com.dy.pipIrrGlobal.daoPr", "com.dy.pipIrrGlobal.daoBa"})
@MapperScan({"com.dy.pipIrrGlobal.daoSe", "com.dy.pipIrrGlobal.daoBa"})
public class PipIrrWebChatApplication {
    public static void main(String[] args) {
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/config/RestTemplateConfig.java
New file
@@ -0,0 +1,81 @@
package com.dy.pipirrWebChat.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.util.List;
//import org.apache.http.client.HttpClient;
/**
 * @author ZhuBaoMin
 * @date 2024-02-23 15:42
 * @LastEditTime 2024-02-23 15:42
 * @Description
 */
@Configuration
public class RestTemplateConfig {
    @Autowired
    private RestTemplateWechatCertConfig restTemplateWechatCertConfig;
    //@Bean
    //public RestTemplate restTemplate() {
    //    return new RestTemplate();
    //}
    //@Bean
    //public RestTemplate restTemplate() {
    //    String mchid = PayInfo.mchid;
    //    RestTemplate restTemplate = null;
    //    try {
    //        KeyStore keyStore = KeyStore.getInstance("PKCS12");
    //        //InputStream cp = this.getClass().getResourceAsStream("apiclient_cert.p12");
    //        FileInputStream instream = new FileInputStream(new File("C:\\webchat\\apiclient_cert.p12"));
    //        keyStore.load(instream, mchid.toCharArray());
    //        // Trust own CA and all self-signed certs
    //        SSLContext sslcontext = SSLContextBuilder.create()
    //                .loadKeyMaterial(keyStore, mchid.toCharArray())
    //                .build();
    //         //Allow TLSv1 protocol only
    //        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, NoopHostnameVerifier.INSTANCE);
    //        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
    //        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
    //
    //        restTemplate = new RestTemplate(factory);
    //        //将转换器的编码换成utf-8
    //        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("utf-8")));
    //        //System.out.println("restTemplate.hashCode():" + restTemplate.hashCode());
    //    } catch (Exception e) {
    //        e.printStackTrace();
    //    }
    //    return restTemplate;
    //}
    //@Bean(name = "wechatRestTemplate")
    @Bean()
    public RestTemplate restTemplate() throws Exception {
        RestTemplate restTemplate = new RestTemplate(restTemplateWechatCertConfig.wechatHttpRequestFactory());
        // 添加拦截器
        //List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
        //RestTemplateWechatCertConfig.MyRequestInterceptor myRequestInterceptor = new RestTemplateWechatCertConfig.MyRequestInterceptor();
        //interceptors.add(myRequestInterceptor);
        //restTemplate.setInterceptors(interceptors);
        // 中文乱码,主要是 StringHttpMessageConverter的默认编码为ISO导致的
        List<HttpMessageConverter<?>> list = restTemplate.getMessageConverters();
        for (HttpMessageConverter converter : list) {
            if (converter instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
                break;
            }
        }
        return restTemplate;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/config/RestTemplateWechatCertConfig.java
New file
@@ -0,0 +1,57 @@
package com.dy.pipirrWebChat.config;
import com.dy.pipirrWebChat.payment.PayInfo;
import okhttp3.OkHttpClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
/**
 * @author ZhuBaoMin
 * @date 2024-02-23 19:18
 * @LastEditTime 2024-02-23 19:18
 * @Description
 */
@Configuration
public class RestTemplateWechatCertConfig {
    String mchid = PayInfo.mchid;
    @Bean
    @ConfigurationProperties(prefix = "org.liurb.core.rest-template.config.connection")
    public ClientHttpRequestFactory wechatHttpRequestFactory() throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        //InputStream cp = this.getClass().getResourceAsStream("apiclient_cert.p12");
        FileInputStream instream = new FileInputStream(new File("C:\\webchat\\apiclient_cert.p12"));
        keyStore.load(instream, mchid.toCharArray());
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, mchid.toCharArray());
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(keyManagerFactory.getKeyManagers(), null, null);
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .sslSocketFactory(context.getSocketFactory(), getDefaultX509TrustManager())
                .build();
        return new OkHttp3ClientHttpRequestFactory(okHttpClient);
    }
    private static X509TrustManager getDefaultX509TrustManager() throws Exception {
        TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        factory.init((KeyStore) null);
        return (X509TrustManager) factory.getTrustManagers()[0];
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/payment/PayHelper.java
New file
@@ -0,0 +1,119 @@
package com.dy.pipirrWebChat.payment;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.Random;
/**
 * @author ZhuBaoMin
 * @date 2024-02-22 20:31
 * @LastEditTime 2024-02-22 20:31
 * @Description
 */
public class PayHelper {
    private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    /**
     * 获取32位随机字符串
     * @return 随机串
     */
    public static String generateRandomString() {
        Random random = new Random();
        StringBuilder sb = new StringBuilder(32);
        for (int i = 0; i < 32; i++) {
            int index = random.nextInt(CHARACTERS.length());
            sb.append(CHARACTERS.charAt(index));
        }
        return sb.toString();
    }
    /**
     * 获取私钥对象
     * @param filename 私钥文件路径
     * @return 私钥对象
     * @throws IOException
     */
    public static PrivateKey getPrivateKey(String filename) throws IOException {
        //String filename = "C:\\webchat\\apiclient_key.pem";
        String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");
        try {
            String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s+", "");
            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePrivate(
                    new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("当前Java环境不支持RSA", e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("无效的密钥格式");
        }
    }
    /**
     * 构造签名串_下单
     * @param method HTTP请求方法
     * @param url URL
     * @param timestamp 时间戳
     * @param nonceStr 随机串
     * @param body 报文主题
     * @return 签名串
     */
    public static String buildMessage_order(String method, String url, long timestamp, String nonceStr, String body) {
        return method + "\n"
                + url + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + body + "\n";
    }
    public static String buildMessage_signAgain(String appid, String timestamp, String nonceStr, String pkg) {
        return appid + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + pkg + "\n";
    }
    /**
     * 签名
     * @param message 被签名信息
     * @param certFileName 私钥证书文件路径
     * @return signature签名值,签名信息中的一项,参与生成签名信息
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws SignatureException
     * @throws IOException
     */
    public static String sign(byte[] message, String certFileName) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, IOException {
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(getPrivateKey(certFileName));
        sign.update(message);
        return Base64.getEncoder().encodeToString(sign.sign());
    }
    /**
     * 获取签名信息
     * @param method
     * @param url
     * @param body
     * @return 签名信息,HTTP头中的签名信息
     * HTTP头:Authorization: 认证类型 签名信息
     * 认证类型,WECHATPAY2-SHA256-RSA2048
     */
    public static String getToken(String method, String url, String body, String nonceStr, Long timestamp, String certFileName) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, SignatureException, InvalidKeyException, NoSuchPaddingException {
        String message = buildMessage_order(method, url, timestamp, nonceStr, body);
        String signature = sign(message.getBytes("utf-8"), certFileName);
        return "mchid=\"" + PayInfo.mchid + "\","
                + "nonce_str=\"" + nonceStr + "\","
                + "timestamp=\"" + timestamp + "\","
                + "serial_no=\"" + PayInfo.serial_no + "\","
                + "signature=\"" + signature + "\"";
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/payment/PayInfo.java
New file
@@ -0,0 +1,157 @@
package com.dy.pipirrWebChat.payment;
/**
 * @author ZhuBaoMin
 * @date 2024-02-22 20:20
 * @LastEditTime 2024-02-22 20:20
 * @Description
 */
public class PayInfo {
    /*
     * 小程序登录API
     */
    public static String loginUrl = "https://api.weixin.qq.com/sns/jscode2session";
    /*
     * 统一下单API
     */
    //public static String orderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    public static String orderUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
    /**
     * 平台证书下载URL
     */
    public static String certificates = "https://api.mch.weixin.qq.com/v3/certificates";
    /*
     * 支付结果通知API
     */
    public static String notifyUrl = "https://www.muxiaobao.com/api/Payment/OrderNotify";
    /*
     * 查询订单API
     */
    public static String queryUrl = "https://api.mch.weixin.qq.com/pay/orderquery";
    /*
     * 申请退款API
     */
    public static String refundUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
    /*
     * 退款通知API
     */
    public static String refundNotifyUrl = "https://www.muxiaobao.com/wxpay/pay.action";
    /*
     * 退款查询API
     */
    public static String refundQueryUrl = "https://api.mch.weixin.qq.com/pay/refundquery";
    /*
     * 小程序唯一标识
     */
    public static String appid = "wxf776aebf73f34962";
    /*
     * 小程序的 app secret
     */
    public static String secret = "b05862b7fa8a944114dbe970c2764ae6";
    /*
     * 小程序的授权类型,登录凭证校验使用
     */
    public static String grantType = "authorization_code";
    /*
     * 商户号(微信支付分配的商户号)
     */
    public static String mchid = "1640721520";
    /*
     * 商户平台设置的密钥key
     */
    public static String key = "DaYuJieShuiYanJiuYuan20230412ABC";
    /**
     * 商户API证书序列号
     */
    public static String serial_no = "52D65AA66405C738670377F467178F4C950E1606";
    /*
     * 终端IP,调用微信支付API的机器IP
     */
    public static String addrIp = "47.104.211.89";
    /*
     * 随机字符串,长度要求在32位以内
     */
    //public static String nonceStr = PayHelper.generateRandomString();
    /*
     * 时间戳 从1970年1月1日00:00:00至今的秒数,即当前的时间
     */
    //public static Long timeStamp = PayHelper.getTimeStamp();
    /*
     * 交易类型,小程序取值JSAPI
     */
    public static String tradeType = "JSAPI";
    /*
     * 签名类型
     */
    //public static String signType = "MD5";
    public static String signType = "RSA";
    /*
     * 商品描述 商品简单描述,该字段请按照规范传递
     */
    //public static String body = "大禹研究院-水费";
    public static String description = "大禹研究院-水费";
    /*
     * 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
     */
    public static String attach = "天津";
    /*
     * 签名,参与签名参数:appid、attach、mch_id、nonce_str、body、out_trade_no、total_fee、spbill_create_ip、notify_url、trade_type、openid
     */
    public String sign = "";
    /**
     * HTTP头认证类型
     */
    public static String schema = "WECHATPAY2-SHA256-RSA2048";
    /**
     * 私钥文件路径
     */
    public static String certFileName = "C:\\webchat\\apiclient_key.pem";
    /*
     * 微信订单号,优先使用
     */
    public static String transactionid = "";
    /*
     * 商户系统内部订单号
     */
    public static String out_trade_no = "";
    /*
     * 商户退款单号
     */
    public static String out_refund_no = "";
    /*
     * 退款金额
     */
    public static Float refundfee;
    /*
     * 订单金额
     */
    public static Float totalfee;
}
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/payment/PaymentCtrl.java
New file
@@ -0,0 +1,258 @@
package com.dy.pipirrWebChat.payment;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.aop.SsoAop;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.common.webUtil.ResultCodeMsg;
import com.dy.pipIrrGlobal.pojoSe.SeWebchatLogonState;
import com.dy.pipirrWebChat.util.OkHttpUtil;
import com.dy.pipirrWebChat.util.RestTemplateUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * @author ZhuBaoMin
 * @date 2024-02-22 15:24
 * @LastEditTime 2024-02-22 15:24
 * @Description
 */
@Slf4j
@Tag(name = "微信支付管理", description = "微信支付各种操作")
@RestController
@RequestMapping(path="payment")
@RequiredArgsConstructor
public class PaymentCtrl {
    private final PaymentSv paymentSv;
    private final RestTemplateUtil restTemplateUtil;
    private String certFileName = PayInfo.certFileName;
    /**
     * 登录凭证校验
     * @param appid 小程序 appId
     * @param secret 小程序 appSecret
     * @param js_code 临时登录凭证code
     * @return
     * @throws Exception
     */
    @Operation(summary = "登录凭证校验", description = "登录凭证校验")
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
                    description = "操作结果:true:成功,false:失败(BaseResponse.content)",
                    content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = Boolean.class))}
            )
    })
    @PostMapping(path = "getSessionId")
    @Transactional(rollbackFor = Exception.class)
    @SsoAop()
    public BaseResponse<Boolean> getSessionId(@RequestParam("appid")  String appid, @RequestParam("secret") String secret, @RequestParam("js_code") String js_code) throws Exception {
        String result = OkHttpUtil.builder().url("https://api.weixin.qq.com/sns/jscode2session")
                .addParam("appid", appid)
                .addParam("secret", secret)
                .addParam("js_code", js_code)
                .initGet()
                .sync();
        JSONObject job = JSONObject.parseObject(result);
        System.out.println(job.getString("session_key"));
        if(job.getLong("errcode") != null && job.getLong("errcode") >= -1) {
            return BaseResponseUtils.buildFail("登录凭证校验失败");
        }
        // 添加登录态记录
        SeWebchatLogonState po = new SeWebchatLogonState();
        po.setOpenId(job.getString("openid"));
        po.setSessionKey(job.getString("session_key"));
        Date createTime = new Date();
        po.setCreateTime(createTime);
        Long id = paymentSv.insert(po);
        if(id == null || id <= 0) {
            return BaseResponseUtils.buildFail("登录态记录添加失败");
        }
        String SessionId = String.valueOf(id);
        return BaseResponseUtils.buildSuccess(SessionId) ;
    }
    @Operation(summary = "下载平台证书", description = "下载平台证书")
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
                    description = "操作结果:true:成功,false:失败(BaseResponse.content)",
                    content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = Boolean.class))}
            )
    })
    @GetMapping(path = "certificates")
    @Transactional(rollbackFor = Exception.class)
    @SsoAop()
    public BaseResponse<JSONObject> certificates() throws Exception {
        //String prepayId = "";
        //SeWebchatLogonState po = paymentSv.selectOne(Long.parseLong(sessionId));
        //String openid = po.getOpenId();
        String method = "GET";
        String httpUrl = "/v3/certificates";
        String nonceStr = PayHelper.generateRandomString();
        Long timestamp = System.currentTimeMillis() / 1000;
        String header = PayInfo.schema + " " + PayHelper.getToken(method, httpUrl, "", nonceStr, timestamp, certFileName);
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", header);
        headers.put("Accept", "application/json");
        JSONObject job_result = restTemplateUtil.get(PayInfo.certificates,null, headers);
        if(job_result != null) {
            JSONArray array = job_result.getJSONArray("data");
            if(array != null && array.size() > 0) {
                for(int i = 0; i < array.size(); i++) {
                    JSONObject job_data = array.getJSONObject(i);
                    String serial_no = job_data.getString("serial_no");
                    String effective_time  = job_data.getString("effective_time");
                    String expire_time  = job_data.getString("expire_time");
                    JSONObject job_certificate = job_data.getJSONObject("encrypt_certificate");
                    String algorithm = job_certificate.getString("algorithm");
                    String nonce  = job_certificate.getString("nonce");
                    String associated_data  = job_certificate.getString("associated_data");
                    String ciphertext  = job_certificate.getString("ciphertext");
                }
            }
        }
        System.out.println(job_result.toJSONString());
        return BaseResponseUtils.buildSuccess(job_result.toJSONString()) ;
    }
    /**
     * JSAPI下单
     * @param sessionId
     * @param orderNumber
     * @param payAmount
     * @return
     * @throws Exception
     */
    @Operation(summary = "统一下单", description = "统一下单")
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
                    description = "操作结果:true:成功,false:失败(BaseResponse.content)",
                    content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = Boolean.class))}
            )
    })
    @PostMapping(path = "unifiedOrder")
    @Transactional(rollbackFor = Exception.class)
    @SsoAop()
    public BaseResponse<Boolean> unifiedOrder(@RequestParam("sessionId")  String sessionId, @RequestParam("orderNumber") String orderNumber, @RequestParam("payAmount") String payAmount) throws Exception {
        String prepayId = "";
        SeWebchatLogonState po = paymentSv.selectOne(Long.parseLong(sessionId));
        String openid = po.getOpenId();
        JSONObject job_body = new JSONObject();
        job_body.put("appid", PayInfo.appid);
        job_body.put("mchid", PayInfo.mchid);
        job_body.put("description", PayInfo.description);
        job_body.put("out_trade_no", orderNumber);
        job_body.put("notify_url", PayInfo.notifyUrl);
        //订单金额
        JSONObject job_amount = new JSONObject();
        job_amount.put("total", 1);
        job_amount.put("currency", "CNY");
        job_body.put("amount", job_amount);
        //支付者
        JSONObject job_payer = new JSONObject();
        job_payer.put("openid", openid);
        job_body.put("payer", job_payer);
        // 获取随机串和时间戳,放在此处以保证
        String nonceStr = PayHelper.generateRandomString();
        Long timestamp = System.currentTimeMillis() / 1000;
        String method = "POST";
        String httpUrl = "/v3/pay/transactions/jsapi";
        String body = job_body.toJSONString();
        String header = PayInfo.schema + " " + PayHelper.getToken(method, httpUrl, body, nonceStr, timestamp, certFileName);
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", header);
        headers.put("Accept", "application/json");
        headers.put("Content-Type", "application/json");
        JSONObject job_result = restTemplateUtil.post(PayInfo.orderUrl, body, headers);
        if(job_result != null) {
            System.out.println(job_result.toString());
            prepayId = job_result.getString("prepay_id");
        }
        //String result = OkHttpUtil.builder().url(PayInfo.orderUrl)
        //        .addBody(body)
        //        .addHeader("Authorization", header)
        //        .addHeader("Accept", "application/json")
        //        .addHeader("Content-Type", "application/json")
        //        .initPost(true)
        //        .sync();
        //System.out.println(result);
        return BaseResponseUtils.buildSuccess(prepayId) ;
    }
    /**
     * 再次签名
     * @param prepayId 预支付交易会话标识
     * @return 小程序调起支付参数
     * @throws Exception
     */
    @Operation(summary = "再次签名", description = "再次签名")
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
                    description = "操作结果:true:成功,false:失败(BaseResponse.content)",
                    content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = Boolean.class))}
            )
    })
    @GetMapping(path = "/signAgain")
    @Transactional(rollbackFor = Exception.class)
    @SsoAop()
    public BaseResponse<JSONObject> signAgain(@RequestParam("prepayId")  String prepayId) throws Exception {
        // 获取随机串和时间戳,放在此处以保证
        String appid = PayInfo.appid;
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String nonceStr = PayHelper.generateRandomString();
        String pkg = "prepay_id=" + prepayId;
        String signType = PayInfo.signType;
        String message = PayHelper.buildMessage_signAgain(appid, timestamp, nonceStr, pkg);
        String paySign = PayHelper.sign(message.getBytes("utf-8"), certFileName);
        JSONObject job_result = new JSONObject();
        job_result.put("timestamp", timestamp);
        job_result.put("nonceStr", nonceStr);
        job_result.put("package", pkg);
        job_result.put("signType", signType);
        job_result.put("paySign", paySign);
        return BaseResponseUtils.buildSuccess(job_result) ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/payment/PaymentSv.java
New file
@@ -0,0 +1,35 @@
package com.dy.pipirrWebChat.payment;
import com.dy.pipIrrGlobal.daoSe.SeWebchatLogonStateMapper;
import com.dy.pipIrrGlobal.pojoSe.SeWebchatLogonState;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author ZhuBaoMin
 * @date 2024-02-22 17:39
 * @LastEditTime 2024-02-22 17:39
 * @Description
 */
@Slf4j
@Service
public class PaymentSv {
    @Autowired
    private SeWebchatLogonStateMapper seWebchatLogonStateMapper;
    /**
     * 添加登录态状态记录
     * @param po
     * @return
     */
    Long insert(SeWebchatLogonState po) {
        seWebchatLogonStateMapper.insert(po);
        return po.getId();
    }
    SeWebchatLogonState selectOne(Long id) {
        return seWebchatLogonStateMapper.selectByPrimaryKey(id);
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/payment/dto/Code2Session.java
New file
@@ -0,0 +1,39 @@
package com.dy.pipirrWebChat.payment.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
 * @author ZhuBaoMin
 * @date 2024-02-22 15:34
 * @LastEditTime 2024-02-22 15:34
 * @Description
 */
@Data
@Schema(name = "登录凭证校验传入对象")
public class Code2Session {
    public static final long serialVersionUID = 202402221335001L;
    /**
     * 小程序 appId
     */
    @Schema(description = "小程序 appId", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotBlank(message = "小程序 appId不能为空")
    private String appid;
    /**
     * 小程序 appSecret
     */
    @Schema(description = "小程序 appSecret", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotBlank(message = "小程序 appSecret不能为空")
    private String secret;
    /**
     * js_code
     */
    @Schema(description = "js_code", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotBlank(message = "js_code不能为空")
    private String js_code;
}
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/util/ICallback.java
New file
@@ -0,0 +1,15 @@
package com.dy.pipirrWebChat.util;
import okhttp3.Call;
/**
 * @author ZhuBaoMin
 * @date 2024-02-22 15:22
 * @LastEditTime 2024-02-22 15:22
 * @Description
 */
public interface ICallback {
    void onSuccess(Call call, String data);
    void onFail(Call call, String errorMsg);
}
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/util/OkHttpUtil.java
New file
@@ -0,0 +1,239 @@
package com.dy.pipirrWebChat.util;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
 * @author ZhuBaoMin
 * @date 2024-02-22 13:39
 * @LastEditTime 2024-02-22 13:39
 * @Description
 */
public class OkHttpUtil {
    private static volatile OkHttpClient okHttpClient = null;
    private static volatile Semaphore semaphore = null;
    private Map<String, String> headerMap;
    private Map<String, Object> paramMap;
    private String url;
    private Request.Builder request;
    private String body;
    private OkHttpUtil() {
        if (Objects.isNull(okHttpClient)) {
            synchronized (OkHttpUtil.class) {
                if (Objects.isNull(okHttpClient)) {
                    TrustManager[] trustManagers = buildTrustManager();
                    okHttpClient = new OkHttpClient.Builder()
                            .connectTimeout(15, TimeUnit.SECONDS)
                            .writeTimeout(20, TimeUnit.SECONDS)
                            .readTimeout(20, TimeUnit.SECONDS)
                            .sslSocketFactory(createSSLSocketFactory(trustManagers), (X509TrustManager)trustManagers[0])
                            .hostnameVerifier((hostname, session) -> true)
                            .retryOnConnectionFailure(true)
                            .build();
                    addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36");
                }
            }
        }
    }
    public OkHttpUtil initGet() {
        request = new Request.Builder().get();
        StringBuilder builder = new StringBuilder(url);
        if (Objects.nonNull(paramMap)) {
            builder.append("?");
            paramMap.forEach((key, value) -> {
                try {
                    builder.append(URLEncoder.encode(key, "utf-8"))
                            .append("=")
                            .append(URLEncoder.encode((String)value, "utf-8"))
                            .append("&");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            });
            builder.deleteCharAt(builder.length() - 1);
        }
        request.url(builder.toString());
        return this;
    }
    public OkHttpUtil initPost(boolean isJson) {
        RequestBody requestBody = null;
        if (isJson) {
            requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), body);
        } else {
            FormBody.Builder formBody = new FormBody.Builder();
            if (Objects.nonNull(paramMap)) {
                paramMap.forEach((x, y) -> formBody.add(x, (String) y));
            }
            requestBody = formBody.build();
        }
        request = new Request.Builder().post(requestBody).url(url);
        return this;
    }
    /**
     * @Description:同步请求
     * @Author: zzc
     * @Date: 2022-12-04 18:06
     * @return: java.lang.String
     **/
    public String sync() throws Exception {
        setHeader(request);
        try {
            Response result = okHttpClient.newCall(request.build()).execute();
            if (result.isSuccessful()) {
                return result.body().string();
            }
            throw new Exception(result.body().string());
        } catch (IOException e) {
            throw new Exception(e.getMessage());
        }
    }
    /**
     * @Description:异步请求,有返回值
     * @Author: zzc
     * @Date: 2022-12-04 18:05
     * @return: java.lang.String
     **/
    public String async() {
        StringBuffer buffer = new StringBuffer();
        setHeader(request);
        okHttpClient.newCall(request.build()).enqueue(new Callback() {
            @Override
            public void onResponse(@NotNull okhttp3.Call call, @NotNull Response response) throws IOException {
                if (Objects.nonNull(response.body())) {
                    buffer.append(response.body().string());
                    getSemaphore().release();
                }
            }
            @Override
            public void onFailure(@NotNull okhttp3.Call call, @NotNull IOException e) {
                buffer.append("请求出错").append(e.getMessage());
            }
        });
        try {
            getSemaphore().acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return buffer.toString();
    }
    private static Semaphore getSemaphore() {
        synchronized (OkHttpUtil.class) {
            if (Objects.isNull(semaphore)) {
                semaphore = new Semaphore(0);
            }
        }
        return semaphore;
    }
    public static OkHttpUtil builder() {
        return new OkHttpUtil();
    }
    public OkHttpUtil url(String url) {
        this.url = url;
        return this;
    }
    public OkHttpUtil addParam(String key, String value) {
        if (Objects.isNull(paramMap)) {
            paramMap = new LinkedHashMap<>(16);
        }
        paramMap.put(key, value);
        return this;
    }
    public OkHttpUtil addBody(String body) {
        this.body = body;
        return this;
    }
    public void setHeader(Request.Builder request) {
        if (Objects.nonNull(headerMap)) {
            headerMap.forEach(request::addHeader);
        }
    }
    public OkHttpUtil addHeader(String key, String value) {
        if (Objects.isNull(headerMap)) {
            headerMap = new LinkedHashMap<>(16);
        }
        headerMap.put(key, value);
        return this;
    }
    /**
     * @Description:生成安全套接字工厂,用于Https请求的证书跳过
     * @Author: zzc
     * @Date: 2022-11-30 16:03
     * @param trustManagers:
     * @return: javax.net.ssl.SSLSocketFactory
     **/
    //private static SSLSocketFactory createSSLSocketFactory(TrustManager[] trustManagers) {
    //    SSLSocketFactory sslSocketFactory = null;
    //    try {
    //        SSLContext ssl = SSLContext.getInstance("SSL");
    //        ssl.init(null, trustManagers, new SecureRandom());
    //        sslSocketFactory = ssl.getSocketFactory();
    //    } catch (Exception e) {
    //        e.printStackTrace();
    //    }
    //    return sslSocketFactory;
    //}
    private static SSLSocketFactory createSSLSocketFactory(TrustManager[] trustManagers) {
        SSLSocketFactory sslSocketFactory = null;
        try {
            SSLContext ssl = SSLContext.getInstance("SSL");
            ssl.init(null, trustManagers, new SecureRandom());
            sslSocketFactory = ssl.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sslSocketFactory;
    }
    private static TrustManager[] buildTrustManager() {
        return new TrustManager[] {
                new X509TrustManager() {
                    @Override
                    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    }
                    @Override
                    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    }
                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                    }
                }
        };
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/java/com/dy/pipirrWebChat/util/RestTemplateUtil.java
New file
@@ -0,0 +1,102 @@
package com.dy.pipirrWebChat.util;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
 * @author ZhuBaoMin
 * @date 2024-02-23 15:42
 * @LastEditTime 2024-02-23 15:42
 * @Description
 */
@Component
public class RestTemplateUtil {
    @Autowired
    private RestTemplate restTemplate;
    //@Qualifier("RestTemplateWithCert")
    //@Resource
    //private RestTemplate restTemplate;
    public JSONObject get(String url, Map<String, Object> queryParams) throws IOException {
        return get(url, queryParams, new HashMap<>(1));
    }
    public JSONObject get(String url, Map<String, Object> queryParams, Map<String, String> headerParams) throws IOException {
        String tempUrl = setParamsByAppendUrl(queryParams, url);
        HttpHeaders headers = new HttpHeaders();
        headerParams.forEach(headers::add);
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(null, headers);
        ResponseEntity<String> response = restTemplate.exchange(tempUrl, HttpMethod.GET, httpEntity, String.class);
        return JSONObject.parseObject(response.getBody());
    }
    public JSONObject get2(String url, Map<String, Object> queryParams, Map<String, String> headerParams) throws IOException {
        String tempUrl = setParamsByPath(queryParams, url);
        HttpHeaders headers = new HttpHeaders();
        headerParams.forEach(headers::add);
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(null, headers);
        ResponseEntity<String> response = restTemplate.exchange(tempUrl, HttpMethod.GET, httpEntity, String.class, queryParams);
        return JSONObject.parseObject(response.getBody());
    }
    public JSONObject post(String url, String json, Map<String, String> headerParams) {
        HttpHeaders headers = new HttpHeaders();
        headerParams.forEach(headers::add);
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        HttpEntity<String> httpEntity = new HttpEntity<>(json, headers);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
        return JSONObject.parseObject(response.getBody());
    }
    private String setParamsByPath(Map<String, Object> queryParams, String url) {
        // url?id={id}&name={name}
        if (queryParams == null || queryParams.isEmpty()) {
            return url;
        }
        StringBuilder sb = new StringBuilder();
        try {
            for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
                sb.append("&").append(entry.getKey()).append("=").append("{").append(entry.getKey()).append("}");
            }
            if (!url.contains("?")) {
                sb.deleteCharAt(0).insert(0, "?");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return url + sb;
    }
    private String setParamsByAppendUrl(Map<String, Object> queryParams, String url) {
        // url?id=1&name=zzc
        if (queryParams == null || queryParams.isEmpty()) {
            return url;
        }
        StringBuilder sb = new StringBuilder();
        try {
            for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
                sb.append("&").append(entry.getKey()).append("=");
                sb.append(entry.getValue());
            }
            if (!url.contains("?")) {
                sb.deleteCharAt(0).insert(0, "?");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return url + sb;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-webchat/src/main/resources/application.yml
@@ -5,12 +5,12 @@
#actutor的web端口
management:
  server:
    port: ${pipIrr.project.actutorPort}
    port: ${pipIrr.webchat.actutorPort}
#web服务端口,8086
server:
  port: ${pipIrr.webchat.webPort}
  servlet:
    context-path: /webchat #web访问上下文路径
    context-path: /webchat #webchat访问上下文路径
    context-parameters:
      #GenerateIdSetSuffixListener中应用,取值范围是0-99
      idSuffix: ${pipIrr.webchat.idSuffix}