diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..019b91a
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..c0ed014
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..1067e4c
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jpa-buddy.xml b/.idea/jpa-buddy.xml
new file mode 100644
index 0000000..898e07a
--- /dev/null
+++ b/.idea/jpa-buddy.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..2943e7c
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 OSSEZ.COM
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f852fb5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,112 @@
+# WeChat-Official-Account-Spring
+
+
+
+
+
+ This project builds by JDK 11 and OpenJ9 for JVM.
+
+
+* [社区和讨论 (community)](https://www.ossez.com/tag/wechat)
+
+Spring Boot API Project for WeChat-J library.
+
+这是一个基于 WeChat-J 和 Spring Boot 的 API 微信公众号测试程序。
+
+我们旨在提供一个初始化的开发框架,能够让应用在使用 Spring Boot 框架的基础上让你的微信公众号快速接入微信平台。
+
+# 项目配置
+
+和所有的 Java 项目的标准配置一样,你首先需要把依赖添加到你的项目中,然后完成属性文件配置。
+
+在这个基础上,需要有一些先决条件。
+
+## 先决条件
+
+需要对微信公众号进行测试,你首先需要有一个微信公众号,如果没有的话,你可以使用微信提供的测试公众号来获得需要的 appID 和
+appsecret。
+
+* [微信测试平台获得测试账号](https://www.ossez.com/t/topic/14281)
+
+## 依赖
+
+项目使用的是 Maven,如果你只希望使用 WeChat-J,你只需要往你的项目中添加依赖即可。
+
+因为我们目前还在对项目进行整理,所以还是使用的 SNAPSHOT 版本。
+
+```xml
+
+
+ com.ossez.wechat
+ wechat-j-oa
+ 0.0.1-SNAPSHOT
+
+```
+
+## 修改配置文件
+
+```properties
+# WeChat Official Cccount Conf
+wechat.official-account.app-id=appId
+wechat.official-account.secret=secret
+wechat.official-account.token=token
+wechat.official-account.aes-key=aesKey
+# 存储配置redis(可选)
+wx.mp.config-storage.type=Jedis # 配置类型: Memory(默认), Jedis, RedisTemplate
+wx.mp.config-storage.key-prefix=wx # 相关redis前缀配置: wx(默认)
+wx.mp.config-storage.redis.host=127.0.0.1
+wx.mp.config-storage.redis.port=6379
+#单机和sentinel同时存在时,优先使用sentinel配置
+#wx.mp.config-storage.redis.sentinel-ips=127.0.0.1:16379,127.0.0.1:26379
+#wx.mp.config-storage.redis.sentinel-name=mymaster
+# http客户端配置
+wx.mp.config-storage.http-client-type=httpclient # http客户端类型: HttpClient(默认), OkHttp, JoddHttp
+wx.mp.config-storage.http-proxy-host=
+wx.mp.config-storage.http-proxy-port=
+wx.mp.config-storage.http-proxy-username=
+wx.mp.config-storage.http-proxy-password=
+# 公众号地址host配置
+#wx.mp.hosts.api-host=http://proxy.com/
+#wx.mp.hosts.open-host=http://proxy.com/
+#wx.mp.hosts.mp-host=http://proxy.com/
+```
+
+## 自动注入的类型
+
+- `WxMpService`
+- `WxMpConfigStorage`
+
+# 联系方式
+
+请使用下面的联系方式和我们联系。
+
+* [社区和讨论](https://www.ossez.com/tag/chat-gpt)
+
+| 联系方式名称 | 联系方式 |
+|------------------|-----------------------------------------------|
+| 电子邮件(Email) | [yhu@ossez.com](mailto:yhu@ossez.com) |
+| QQ 或微信(WeChat) | 103899765 |
+| QQ 交流群 | 15186112 |
+| 社区论坛 (Community) | https://www.ossez.com/c/computer-technology/7 |
+
+# 公众平台
+
+我们建议您通过社区论坛来和我们进行沟通,请关注我们公众平台上的账号
+
+## 微信公众号
+
+
+
+## 头条号
+
+我们也在头条号上创建了我们的公众号,请扫描下面的 QR 关注我们的头条号。
+
+
+
+## 知乎
+
+请关注我们的知乎:https://www.zhihu.com/people/huyuchengus
+
+# License
+
+[WeChat-Official-Account-Spring is licensed under the MIT License](https://src.ossez.com/honeymoose/WeChat-Official-Account-Spring/src/branch/master/LICENSE)
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..0fd5b44
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,178 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.5
+
+
+ com.ossez.openai
+ openai-spring
+ 0.0.1-SNAPSHOT
+ OpenAI- Spring Demo
+ OpenAI- Demo Example
+
+
+ The MIT license
+ https://opensource.org/licenses/mit-license.php
+ repo
+
+
+
+
+ YuCheng Hu
+ honeymoose
+ huyuchengus@gmail.com
+ -5
+ Open Source
+
+ Sr. Java Developer
+
+
+
+
+
+
+ com.ossez.wechat
+ wechat-j-oa
+ 0.0.1-SNAPSHOT
+
+
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.36
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.24
+ provided
+
+
+
+ redis.clients
+ jedis
+ compile
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+ 3.0.1
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.assertj
+ assertj-core
+ 3.24.1
+ test
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 3.0.0
+
+
+ default-deploy
+ deploy
+
+ deploy
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.4.1
+
+ 17
+
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.10.1
+
+ 17
+
+
+
+
+
diff --git a/src/main/java/com/ossez/openai/demo/Application.java b/src/main/java/com/ossez/openai/demo/Application.java
new file mode 100644
index 0000000..074d6ba
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/Application.java
@@ -0,0 +1,13 @@
+package com.ossez.openai.demo;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@Slf4j
+public class Application {
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/src/main/java/com/ossez/openai/demo/common/enums/HttpClientCategory.java b/src/main/java/com/ossez/openai/demo/common/enums/HttpClientCategory.java
new file mode 100644
index 0000000..48c2fc4
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/common/enums/HttpClientCategory.java
@@ -0,0 +1,12 @@
+package com.ossez.openai.demo.common.enums;
+
+/**
+ * User different http client to make api call.
+ * We should only keep OK_HTTP, this enough for package
+ *
+ * @author YuCheng Hu
+ */
+public enum HttpClientCategory {
+ OK_HTTP, HTTP_CLIENT
+
+}
diff --git a/src/main/java/com/ossez/openai/demo/common/enums/StorageCategory.java b/src/main/java/com/ossez/openai/demo/common/enums/StorageCategory.java
new file mode 100644
index 0000000..936ac21
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/common/enums/StorageCategory.java
@@ -0,0 +1,13 @@
+package com.ossez.openai.demo.common.enums;
+
+/**
+ * WeChat's Storage Category
+ *
+ * We provide implement for MEM(RAM) and REDIS
+ *
+ * @author YuCheng Hu
+ */
+@Deprecated
+public enum StorageCategory {
+ MEM, REDIS
+}
diff --git a/src/main/java/com/ossez/openai/demo/config/WeChatConfiguration.java b/src/main/java/com/ossez/openai/demo/config/WeChatConfiguration.java
new file mode 100644
index 0000000..6585aef
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/config/WeChatConfiguration.java
@@ -0,0 +1,57 @@
+package com.ossez.openai.demo.config;
+
+import com.ossez.wechat.common.config.ConfigStorage;
+import com.ossez.wechat.common.exception.WxErrorException;
+import com.ossez.openai.demo.common.enums.HttpClientCategory;
+import com.ossez.openai.demo.properties.WeChatOfficialAccountProperties;
+import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
+import com.ossez.wechat.oa.api.impl.okhttp.WeChatPlatformService;
+import com.ossez.wechat.oa.api.impl.okhttp.WeChatOfficialAccountServiceOkHttp;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.Scope;
+
+/**
+ * .
+ *
+ * @author someone
+ */
+@Configuration
+@EnableConfigurationProperties(WeChatOfficialAccountProperties.class)
+@Import({WeChatStorageAutoConfiguration.class})
+public class WeChatConfiguration {
+
+
+ /**
+ * weChat Service Inject
+ */
+ @Bean
+ @ConditionalOnMissingBean
+ public WeChatOfficialAccountService weChatOfficialAccountService(ConfigStorage configStorage, WeChatOfficialAccountProperties weChatOfficialAccountProperties) {
+ HttpClientCategory httpClientCategory = weChatOfficialAccountProperties.getWeChatDataStorage().getHttpClientCategory();
+ WeChatOfficialAccountService weChatOfficialAccountService = new WeChatOfficialAccountServiceOkHttp();
+
+ weChatOfficialAccountService.setWxMpConfigStorage(configStorage);
+ return weChatOfficialAccountService;
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+ public WeChatPlatformService weChatPlatformService(WeChatOfficialAccountService weChatOfficialAccountService) throws WxErrorException {
+ weChatOfficialAccountService.getAccessToken();
+ return new WeChatPlatformService(weChatOfficialAccountService);
+ }
+//
+// @Bean
+// @ConditionalOnMissingBean
+// @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+// public WeChatMsgService weChatMsgService(WeChatOfficialAccountService weChatOfficialAccountService) throws WxErrorException {
+// return new WeChatMsgService(weChatOfficialAccountService);
+//
+// }
+}
diff --git a/src/main/java/com/ossez/openai/demo/config/WeChatStorageAutoConfiguration.java b/src/main/java/com/ossez/openai/demo/config/WeChatStorageAutoConfiguration.java
new file mode 100644
index 0000000..df2cbdc
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/config/WeChatStorageAutoConfiguration.java
@@ -0,0 +1,109 @@
+package com.ossez.openai.demo.config;
+
+import com.ossez.wechat.common.config.ConfigStorage;
+import com.ossez.openai.demo.common.enums.StorageCategory;
+import com.ossez.openai.demo.model.entity.WeChatDataStorage;
+import com.ossez.openai.demo.properties.WeChatOfficialAccountProperties;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import com.ossez.wechat.common.redis.RedisTemplateWxRedisOps;
+import com.ossez.wechat.common.redis.WxRedisOps;
+import com.ossez.wechat.common.config.WxMpHostConfig;
+import com.ossez.wechat.common.config.DefaultConfigStorage;
+import com.ossez.wechat.common.config.RedisConfigStorage;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.core.StringRedisTemplate;
+
+/**
+ * 微信公众号存储策略自动配置.
+ *
+ * @author Luo
+ */
+@Slf4j
+@Configuration
+@RequiredArgsConstructor
+public class WeChatStorageAutoConfiguration {
+ private final ApplicationContext applicationContext;
+
+ private final WeChatOfficialAccountProperties weChatOfficialAccountProperties;
+
+ @Bean
+ @ConditionalOnMissingBean(ConfigStorage.class)
+ public ConfigStorage wxMpConfigStorage() {
+ StorageCategory type = weChatOfficialAccountProperties.getWeChatDataStorage().getType();
+ ConfigStorage config;
+ switch (type) {
+ case REDIS:
+ config = redisTemplateConfigStorage();
+ break;
+ default:
+ config = defaultConfigStorage();
+ break;
+ }
+ // wx host config
+ if (null != weChatOfficialAccountProperties.getHosts() && StringUtils.isNotEmpty(weChatOfficialAccountProperties.getHosts().getApiHost())) {
+ WxMpHostConfig hostConfig = new WxMpHostConfig();
+ hostConfig.setApiHost(weChatOfficialAccountProperties.getHosts().getApiHost());
+ hostConfig.setMpHost(weChatOfficialAccountProperties.getHosts().getMpHost());
+ hostConfig.setOpenHost(weChatOfficialAccountProperties.getHosts().getOpenHost());
+ config.setHostConfig(hostConfig);
+ }
+ return config;
+ }
+
+ private ConfigStorage defaultConfigStorage() {
+ DefaultConfigStorage config = new DefaultConfigStorage();
+ configWeChatServer(config);
+ return config;
+ }
+
+
+ private ConfigStorage redisTemplateConfigStorage() {
+ StringRedisTemplate redisTemplate = null;
+ try {
+ redisTemplate = applicationContext.getBean(StringRedisTemplate.class);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ try {
+ if (null == redisTemplate) {
+ redisTemplate = (StringRedisTemplate) applicationContext.getBean("stringRedisTemplate");
+ }
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+
+ if (null == redisTemplate) {
+ redisTemplate = (StringRedisTemplate) applicationContext.getBean("redisTemplate");
+ }
+
+ WxRedisOps redisOps = new RedisTemplateWxRedisOps(redisTemplate);
+ RedisConfigStorage redisConfigStorage = new RedisConfigStorage(redisOps,
+ weChatOfficialAccountProperties.getWeChatDataStorage().getKeyPrefix());
+
+ configWeChatServer(redisConfigStorage);
+ return redisConfigStorage;
+ }
+
+ private void configWeChatServer(DefaultConfigStorage defaultConfigStorage) {
+ WeChatOfficialAccountProperties properties = weChatOfficialAccountProperties;
+ WeChatDataStorage weChatDataStorage = weChatOfficialAccountProperties.getWeChatDataStorage();
+
+ defaultConfigStorage.setAppId(properties.getAppId());
+ defaultConfigStorage.setSecret(properties.getSecret());
+ defaultConfigStorage.setToken(properties.getToken());
+ defaultConfigStorage.setAesKey(properties.getAesKey());
+
+ defaultConfigStorage.setHttpProxyHost(weChatDataStorage.getHttpProxyHost());
+ defaultConfigStorage.setHttpProxyUsername(weChatDataStorage.getHttpProxyUsername());
+ defaultConfigStorage.setHttpProxyPassword(weChatDataStorage.getHttpProxyPassword());
+ if (weChatDataStorage.getHttpProxyPort() != null) {
+ defaultConfigStorage.setHttpProxyPort(weChatDataStorage.getHttpProxyPort());
+ }
+ }
+
+}
diff --git a/src/main/java/com/ossez/openai/demo/controller/OpenAIController.java b/src/main/java/com/ossez/openai/demo/controller/OpenAIController.java
new file mode 100644
index 0000000..c0cf887
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/controller/OpenAIController.java
@@ -0,0 +1,80 @@
+package com.ossez.openai.demo.controller;
+
+import com.ossez.wechat.common.exception.WxErrorException;
+import com.ossez.wechat.common.model.res.QueryQuotaResponse;
+import com.ossez.openai.demo.data.repository.redis.StudentRepository;
+import com.ossez.openai.demo.service.OpenAIService;
+import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * WeChatController to process WeChat request
+ *
+ * @author YuCheng Hu
+ */
+@RestController
+@RequestMapping(value = "/openai")
+@Slf4j
+public class OpenAIController {
+
+ private final WeChatOfficialAccountService weChatOfficialAccountService;
+ private final OpenAIService openAIService;
+ private final StudentRepository studentRepository;
+
+ @Autowired
+ public OpenAIController(WeChatOfficialAccountService weChatOfficialAccountService, OpenAIService openAIService, StudentRepository studentRepository) {
+ this.weChatOfficialAccountService = weChatOfficialAccountService;
+ this.openAIService = openAIService;
+ this.studentRepository = studentRepository;
+ }
+
+ /**
+ * Get weChat access token
+ *
+ * @return The access token
+ * @throws WxErrorException WeChat API Error
+ */
+ @GetMapping("/chat")
+ @ResponseBody
+ public String getAccessToken() throws WxErrorException {
+ log.debug("Get access token from WeChat");
+ return weChatOfficialAccountService.getAccessToken(true);
+ }
+
+ @GetMapping("/config")
+ @ResponseBody
+ public String getDomainIPs() throws WxErrorException {
+ log.debug("Get access token from WeChat");
+ return openAIService.getDomainIPs();
+ }
+
+// @GetMapping("/networkcheck")
+// @ResponseBody
+// public NetworkCheckResponse checkNetwork() throws WxErrorException {
+// log.debug("Get access token from WeChat");
+// return weChatPlatformService.checkNetwork();
+// }
+//
+ @PostMapping("/session")
+ @ResponseBody
+ public QueryQuotaResponse queryQuota() throws WxErrorException {
+ log.debug("Get access token from WeChat");
+ return openAIService.queryQuota();
+ }
+ @PostMapping("/verify")
+ @ResponseBody
+ public QueryQuotaResponse verify() throws WxErrorException {
+ log.debug("Get access token from WeChat");
+ return openAIService.queryQuota();
+ }
+
+ @GetMapping("/message/send")
+ @ResponseBody
+ public String sendMessage() throws WxErrorException {
+ log.debug("Get access token from WeChat");
+ return openAIService.sendMessage();
+ }
+
+}
diff --git a/src/main/java/com/ossez/openai/demo/data/repository/redis/StudentRepository.java b/src/main/java/com/ossez/openai/demo/data/repository/redis/StudentRepository.java
new file mode 100644
index 0000000..350a869
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/data/repository/redis/StudentRepository.java
@@ -0,0 +1,9 @@
+package com.ossez.openai.demo.data.repository.redis;
+
+
+import com.ossez.openai.demo.model.entity.Student;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface StudentRepository extends CrudRepository {}
diff --git a/src/main/java/com/ossez/openai/demo/model/entity/Student.java b/src/main/java/com/ossez/openai/demo/model/entity/Student.java
new file mode 100644
index 0000000..0fecbce
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/model/entity/Student.java
@@ -0,0 +1,62 @@
+package com.ossez.openai.demo.model.entity;
+
+import org.springframework.data.redis.core.RedisHash;
+
+import java.io.Serializable;
+
+@RedisHash("Student")
+public class Student implements Serializable {
+
+ public enum Gender {
+ MALE, FEMALE
+ }
+
+ private String id;
+ private String name;
+ private Gender gender;
+ private int grade;
+
+ public Student(String id, String name, Gender gender, int grade) {
+ this.id = id;
+ this.name = name;
+ this.gender = gender;
+ this.grade = grade;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Gender getGender() {
+ return gender;
+ }
+
+ public void setGender(Gender gender) {
+ this.gender = gender;
+ }
+
+ public int getGrade() {
+ return grade;
+ }
+
+ public void setGrade(int grade) {
+ this.grade = grade;
+ }
+
+ @Override
+ public String toString() {
+ return "Student{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", gender=" + gender + ", grade=" + grade + '}';
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ossez/openai/demo/model/entity/WeChatDataStorage.java b/src/main/java/com/ossez/openai/demo/model/entity/WeChatDataStorage.java
new file mode 100644
index 0000000..043783c
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/model/entity/WeChatDataStorage.java
@@ -0,0 +1,28 @@
+package com.ossez.openai.demo.model.entity;
+
+import com.ossez.openai.demo.common.enums.HttpClientCategory;
+import com.ossez.openai.demo.common.enums.StorageCategory;
+import com.ossez.openai.demo.properties.RedisProperties;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+
+import java.io.Serializable;
+
+@Getter
+@Setter
+@Accessors(chain = true)
+public class WeChatDataStorage implements Serializable {
+ private static final long serialVersionUID = -94405301936095366L;
+ private StorageCategory type = StorageCategory.MEM;
+ private String keyPrefix = "wx";
+ @NestedConfigurationProperty
+ private final RedisProperties redis = new RedisProperties();
+ private HttpClientCategory httpClientCategory = HttpClientCategory.OK_HTTP;
+ private String httpProxyHost;
+ private Integer httpProxyPort;
+ private String httpProxyUsername;
+ private String httpProxyPassword;
+
+}
diff --git a/src/main/java/com/ossez/openai/demo/model/entity/WeChatHost.java b/src/main/java/com/ossez/openai/demo/model/entity/WeChatHost.java
new file mode 100644
index 0000000..ce093eb
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/model/entity/WeChatHost.java
@@ -0,0 +1,16 @@
+package com.ossez.openai.demo.model.entity;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+public class WeChatHost implements Serializable {
+ private static final long serialVersionUID = -7648920647310280817L;
+ private String apiHost;
+ private String openHost;
+ private String mpHost;
+
+}
diff --git a/src/main/java/com/ossez/openai/demo/properties/RedisProperties.java b/src/main/java/com/ossez/openai/demo/properties/RedisProperties.java
new file mode 100644
index 0000000..5eeff20
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/properties/RedisProperties.java
@@ -0,0 +1,56 @@
+package com.ossez.openai.demo.properties;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * redis 配置属性.
+ *
+ * @author Binary Wang
+ * created on 2020-08-30
+ */
+@Data
+public class RedisProperties implements Serializable {
+ private static final long serialVersionUID = -5924815351660074401L;
+
+ /**
+ * 主机地址.
+ */
+ private String host = "127.0.0.1";
+
+ /**
+ * 端口号.
+ */
+ private int port = 6379;
+
+ /**
+ * 密码.
+ */
+ private String password;
+
+ /**
+ * 超时.
+ */
+ private int timeout = 2000;
+
+ /**
+ * 数据库.
+ */
+ private int database = 0;
+
+ /**
+ * sentinel ips
+ */
+ private String sentinelIps;
+
+ /**
+ * sentinel name
+ */
+ private String sentinelName;
+
+ private Integer maxActive;
+ private Integer maxIdle;
+ private Integer maxWaitMillis;
+ private Integer minIdle;
+}
diff --git a/src/main/java/com/ossez/openai/demo/properties/WeChatOfficialAccountProperties.java b/src/main/java/com/ossez/openai/demo/properties/WeChatOfficialAccountProperties.java
new file mode 100644
index 0000000..b7a0600
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/properties/WeChatOfficialAccountProperties.java
@@ -0,0 +1,25 @@
+package com.ossez.openai.demo.properties;
+
+
+import com.ossez.openai.demo.model.entity.WeChatDataStorage;
+import com.ossez.openai.demo.model.entity.WeChatHost;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * WeChat Official Account Config
+ *
+ * @author YuCheng Hu
+ */
+@Data
+@ConfigurationProperties(prefix = "wechat.official-account")
+public class WeChatOfficialAccountProperties {
+ private String appId; //微信公众号 appId
+ private String secret; //微信公众号 secret
+ private String token; //微信公众号 token
+ private String aesKey; //微信公众号 aesKey
+ private WeChatHost hosts; //自定义 host 配置
+ private final WeChatDataStorage weChatDataStorage = new WeChatDataStorage();
+
+
+}
diff --git a/src/main/java/com/ossez/openai/demo/service/OpenAIService.java b/src/main/java/com/ossez/openai/demo/service/OpenAIService.java
new file mode 100644
index 0000000..71393d6
--- /dev/null
+++ b/src/main/java/com/ossez/openai/demo/service/OpenAIService.java
@@ -0,0 +1,59 @@
+package com.ossez.openai.demo.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ossez.wechat.common.exception.WxErrorException;
+import com.ossez.wechat.common.model.req.CustomMessage;
+import com.ossez.wechat.common.model.res.QueryQuotaResponse;
+import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
+import com.ossez.wechat.oa.api.impl.okhttp.WeChatMsgService;
+import com.ossez.wechat.oa.api.impl.okhttp.WeChatPlatformService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author XieYang, YuCheng
+ * @Date: 2022/10/14/16:17
+ * @Description:
+ */
+@Service
+@Slf4j
+public class OpenAIService {
+ private final WeChatOfficialAccountService weChatOfficialAccountService;
+ private final ObjectMapper objectMapper;
+
+
+ @Autowired
+ public OpenAIService(WeChatOfficialAccountService weChatOfficialAccountService, ObjectMapper objectMapper) throws WxErrorException {
+ this.weChatOfficialAccountService = weChatOfficialAccountService;
+ this.objectMapper = objectMapper;
+ }
+
+
+ /**
+ * Get WeChatLoginQRUrl
+ *
+ * @return
+ */
+ public String getDomainIPs() throws WxErrorException {
+ return new WeChatPlatformService(weChatOfficialAccountService).getDomainIPs();
+ }
+
+ public QueryQuotaResponse queryQuota() throws WxErrorException {
+ return new WeChatPlatformService(weChatOfficialAccountService).queryQuota();
+ }
+
+ public String sendMessage() throws WxErrorException {
+ CustomMessage.KfText kfText = new CustomMessage.KfText("微信异步消息发送");
+ CustomMessage customMessage = new CustomMessage();
+ customMessage.setToUser("o9phd5jz_We8mPs1ovmyjud97Ock");
+ customMessage.setMsgType("text");
+ customMessage.setText(kfText);
+
+ return new WeChatMsgService(weChatOfficialAccountService).sendMessage(customMessage);
+ }
+
+
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000..627bd9e
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1,54 @@
+server.port=8080
+
+spring.batch.job.enabled = false
+spring.batch.jdbc.initialize-schema=ALWAYS
+
+logging.level.org.springframework=INFO
+logging.level.root=DEBUG
+
+spring.jpa.show-sql=false
+spring.jpa.hibernate.ddl-auto=none
+spring.jpa.hibernate.use-new-id-generator-mappings=false
+
+#spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
+#spring.datasource.url=
+#spring.datasource.username=
+#spring.datasource.password=
+
+spring.datasource.url=jdbc:h2:mem:test
+spring.datasource.driverClassName=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=password
+spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
+spring.h2.console.enabled=true
+spring.h2.console.path=/h2-console
+
+spring.datasource.hikari.connection-timeout=50000
+spring.datasource.hikari.idle-timeout=300000
+spring.datasource.hikari.max-lifetime=900000
+spring.datasource.hikari.maximum-pool-size=10
+spring.datasource.hikari.minimum-idle=10
+spring.datasource.hikari.pool-name=ConnPool
+spring.datasource.hikari.connection-test-query=select 1 from dual
+
+spring.datasource.hikari.data-source-properties.cachePrepStmts=true
+spring.datasource.hikari.data-source-properties.prepStmtCacheSize=250
+spring.datasource.hikari.data-source-properties.prepStmtCacheSqlLimit=2048
+spring.datasource.hikari.data-source-properties.useServerPrepStmts=true
+spring.datasource.hikari.data-source-properties.useLocalSessionState=true
+spring.datasource.hikari.data-source-properties.rewriteBatchedStatements=true
+spring.datasource.hikari.data-source-properties.cacheResultSetMetadata=true
+spring.datasource.hikari.data-source-properties.cacheServerConfiguration=true
+spring.datasource.hikari.data-source-properties.elideSetAutoCommits=true
+spring.datasource.hikari.data-source-properties.maintainTimeStats=false
+
+# REDIS
+spring.redis.host=localhost
+spring.redis.port=6379
+
+# KEY
+wechat.official-account.app-id = wx637b82a7f94123ef
+wechat.official-account.secret = 343cecbc44d69e45367a65cc9b4d3925
+wechat.official-account.token = 0b01a700891d4a2f93a4323771c32455
+wechat.official-account.aes-key = aesKey
+
diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql
new file mode 100644
index 0000000..c502b4e
--- /dev/null
+++ b/src/main/resources/data.sql
@@ -0,0 +1,3 @@
+INSERT INTO CITY VALUES (11, 'Delhi', 110001);
+INSERT INTO CITY VALUES (12, 'Kanpur', 208001);
+INSERT INTO CITY VALUES (13, 'Lucknow', 226001);
\ No newline at end of file
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 0000000..bd8ebdf
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+ %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+ true
+
+
+ /var/log/usreio/%d{yyyy-MM-dd}/usreio-debug.log
+
+
+ 30
+ 3GB
+
+
+ true
+ true
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+ true
+
+ ERROR
+
+
+
+ /var/log/usreio/%d{yyyy-MM-dd}/usreio-error.log
+
+
+ 30
+ 3GB
+
+
+ true
+ true
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql
new file mode 100644
index 0000000..ae0ef2b
--- /dev/null
+++ b/src/main/resources/schema.sql
@@ -0,0 +1,7 @@
+DROP TABLE IF EXISTS CITY;
+CREATE TABLE CITY
+(
+ city_code INT AUTO_INCREMENT PRIMARY KEY,
+ city_name VARCHAR NOT NULL,
+ city_pincode INT NOT NULL
+);
\ No newline at end of file
diff --git a/src/test/java/com/ossez/openai/demo/DataTest.java b/src/test/java/com/ossez/openai/demo/DataTest.java
new file mode 100644
index 0000000..de14711
--- /dev/null
+++ b/src/test/java/com/ossez/openai/demo/DataTest.java
@@ -0,0 +1,52 @@
+package com.ossez.openai.demo;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * Email Testing
+ *
+ * @author YuCheng
+ */
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@Slf4j
+class DataTest {
+
+ @Test
+ public void testStartAndEndDateTime() {
+
+// List reqIds = Arrays.asList(1, 2);
+// List reqs = Arrays.asList(1);
+// Map map1 = reqIds.stream().collect(Collectors.toMap(Function.identity(), item -> reqs.contains(item)));
+// Map map2 = reqIds.stream().collect(Collectors.toMap(Function.identity(), reqs::contains));
+//
+// log.debug("Map Size {}",11+20);
+//
+// log.debug("Map Size {}", map2);
+//
+//
+// List shiftIds = Arrays.asList(1, 2);
+// Map shiftIdMaps = new HashMap();
+// shiftIdMaps.put(1, Boolean.TRUE);
+// List reponse = shiftIds.stream().filter(item -> shiftIdMaps.get(item) == Boolean.TRUE).collect(Collectors.toListbi());
+// log.debug("Map Size {}", reponse);
+//
+// log.debug("Map Size {}",map2);
+
+ Double test = 0.1;
+// Objects.nonNull(test)
+
+ System.out.println( NumberUtils.DOUBLE_ZERO.equals(test));
+
+ }
+
+
+}
+
+
diff --git a/src/test/java/com/ossez/openai/demo/WeChatTest.java b/src/test/java/com/ossez/openai/demo/WeChatTest.java
new file mode 100644
index 0000000..47d98d6
--- /dev/null
+++ b/src/test/java/com/ossez/openai/demo/WeChatTest.java
@@ -0,0 +1,68 @@
+package com.ossez.openai.demo;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.io.SAXReader;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Email Testing
+ *
+ * @author YuCheng
+ */
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@Slf4j
+class WeChatTest {
+
+ private String wechatMessageStr = StringUtils.EMPTY;
+
+ @BeforeEach
+ protected void setUp() throws Exception {
+ this.wechatMessageStr = (" \n" +
+ " \n" +
+ " \n" +
+ " 1348831860 \n" +
+ " \n" +
+ " \n" +
+ " 1234567890123456 \n" +
+ " xxxx \n" +
+ " xxxx \n" +
+ " ");
+
+ }
+
+ @AfterEach
+ protected void tearDown() throws Exception {
+ }
+
+
+ @Test
+ public void testToWeChatMessage() {
+ SAXReader xmlReader = new SAXReader();
+ Document document = null;
+
+
+
+ try {
+ document = xmlReader.read(IOUtils.toInputStream(wechatMessageStr, StandardCharsets.UTF_8));
+
+
+
+
+// log.debug("WeChat Message Content - [{}]", weChatMessage.getContent());
+ } catch (DocumentException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
+
diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties
new file mode 100644
index 0000000..3e98aab
--- /dev/null
+++ b/src/test/resources/application.properties
@@ -0,0 +1,42 @@
+server.port=8080
+
+spring.batch.job.enabled = false
+spring.batch.jdbc.initialize-schema=ALWAYS
+
+logging.level.org.springframework=INFO
+logging.level.root=DEBUG
+
+spring.jpa.show-sql=false
+spring.jpa.hibernate.ddl-auto=none
+spring.jpa.hibernate.use-new-id-generator-mappings=false
+
+spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
+spring.datasource.url=
+spring.datasource.username=
+spring.datasource.password=
+
+spring.datasource.hikari.connection-timeout=50000
+spring.datasource.hikari.idle-timeout=300000
+spring.datasource.hikari.max-lifetime=900000
+spring.datasource.hikari.maximum-pool-size=10
+spring.datasource.hikari.minimum-idle=10
+spring.datasource.hikari.pool-name=ConnPool
+spring.datasource.hikari.connection-test-query=select 1 from dual
+
+spring.datasource.hikari.data-source-properties.cachePrepStmts=true
+spring.datasource.hikari.data-source-properties.prepStmtCacheSize=250
+spring.datasource.hikari.data-source-properties.prepStmtCacheSqlLimit=2048
+spring.datasource.hikari.data-source-properties.useServerPrepStmts=true
+spring.datasource.hikari.data-source-properties.useLocalSessionState=true
+spring.datasource.hikari.data-source-properties.rewriteBatchedStatements=true
+spring.datasource.hikari.data-source-properties.cacheResultSetMetadata=true
+spring.datasource.hikari.data-source-properties.cacheServerConfiguration=true
+spring.datasource.hikari.data-source-properties.elideSetAutoCommits=true
+spring.datasource.hikari.data-source-properties.maintainTimeStats=false
+
+# KEY
+wechat.official-account.app-id = wx637b82a7f94123ef
+wechat.official-account.secret = 343cecbc44d69e45367a65cc9b4d3925
+wechat.official-account.token = 0b01a700891d4a2f93a4323771c32455
+wechat.official-account.aes-key = aesKey
+
diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml
new file mode 100644
index 0000000..bd8ebdf
--- /dev/null
+++ b/src/test/resources/logback.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+ %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+ true
+
+
+ /var/log/usreio/%d{yyyy-MM-dd}/usreio-debug.log
+
+
+ 30
+ 3GB
+
+
+ true
+ true
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+ true
+
+ ERROR
+
+
+
+ /var/log/usreio/%d{yyyy-MM-dd}/usreio-error.log
+
+
+ 30
+ 3GB
+
+
+ true
+ true
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file