OSS-165 初始化项目提交

This commit is contained in:
YuCheng Hu 2023-03-29 15:42:55 -04:00
parent 8e4a7d936e
commit 698f95ad5b
29 changed files with 1295 additions and 0 deletions

19
.idea/compiler.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="openai-spring" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="openai-spring" options="-parameters" />
</option>
</component>
</project>

7
.idea/encodings.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-parent/2.7.5/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
</component>
</project>

30
.idea/jarRepositories.xml Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="ossez-repo-snapshots" />
<option name="name" value="OSSEZ Private Snapshots" />
<option name="url" value="https://repo.ossez.com/repository/maven-snapshots/" />
</remote-repository>
<remote-repository>
<option name="id" value="ossez-repo-releases" />
<option name="name" value="OSSEZ Private Releases" />
<option name="url" value="https://repo.ossez.com/repository/maven-releases/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.ossez.com/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

7
.idea/jpa-buddy.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JpaBuddyIdeaProjectConfig">
<option name="defaultUnitInitialized" value="true" />
<option name="renamerInitialized" value="true" />
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

21
LICENSE Normal file
View File

@ -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.

112
README.md Normal file
View File

@ -0,0 +1,112 @@
# WeChat-Official-Account-Spring
<p align="center">
<a href="https://github.com/honeymoose">
<img height=85 src="https://avatars1.githubusercontent.com/u/45009982?s=200&v=4">
</a>
<br>This project builds by JDK 11 and OpenJ9 for JVM.
</p>
* [社区和讨论 (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
<dependency>
<groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-oa</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
```
## 修改配置文件
```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 |
# 公众平台
我们建议您通过社区论坛来和我们进行沟通,请关注我们公众平台上的账号
## 微信公众号
![](https://cdn.ossez.com/img/cwikius/cwikius-qr-wechat-search-w400.png)
## 头条号
我们也在头条号上创建了我们的公众号,请扫描下面的 QR 关注我们的头条号。
![](https://cdn.ossez.com/img/cwikius/cwikus-qr-toutiao.png)
## 知乎
请关注我们的知乎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)

178
pom.xml Normal file
View File

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/>
</parent>
<groupId>com.ossez.openai</groupId>
<artifactId>openai-spring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>OpenAI- Spring Demo</name>
<description>OpenAI- Demo Example</description>
<licenses>
<license>
<name>The MIT license</name>
<url>https://opensource.org/licenses/mit-license.php</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>YuCheng Hu</name>
<id>honeymoose</id>
<email>huyuchengus@gmail.com</email>
<timezone>-5</timezone>
<organization>Open Source</organization>
<roles>
<role>Sr. Java Developer</role>
</roles>
</developer>
</developers>
<dependencies>
<dependency>
<groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-oa</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- LOGGING WITH SELF4J AND LOG4J2 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<scope>compile</scope>
</dependency>
<!-- SPRING -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- TEST -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.24.1</version>
<scope>test</scope>
</dependency>
<!--/ TEST -->
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>default-deploy</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<source>17</source>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<release>17</release>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -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);
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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);
//
// }
}

View File

@ -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());
}
}
}

View File

@ -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();
}
}

View File

@ -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<Student, String> {}

View File

@ -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 + '}';
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1,56 @@
package com.ossez.openai.demo.properties;
import lombok.Data;
import java.io.Serializable;
/**
* redis 配置属性.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* 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;
}

View File

@ -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();
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" ?>
<configuration debug="true">
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned by default the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<!-- FILE-DEBUG -->
<appender name="FILE-DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<prudent>true</prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>/var/log/usreio/%d{yyyy-MM-dd}/usreio-debug.log</fileNamePattern>
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<append>true</append>
<immediateFlush>true</immediateFlush>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- FILE-ERROR -->
<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<prudent>true</prudent>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>/var/log/usreio/%d{yyyy-MM-dd}/usreio-error.log</fileNamePattern>
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<append>true</append>
<immediateFlush>true</immediateFlush>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- LOGGER -->
<logger name="com.ossez" level="DEBUG"/>
<logger name="org.apache" level="INFO"/>
<logger name="org.mariadb" level="INFO"/>
<logger name="org.hibernate" level="INFO"/>
<logger name="org.springframework" level="INFO"/>
<!-- ROOT AND APPENDER -->
<root level="debug">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE-DEBUG"/>
<appender-ref ref="FILE-ERROR"/>
</root>
</configuration>

View File

@ -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
);

View File

@ -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<Integer> reqIds = Arrays.asList(1, 2);
// List<Integer> reqs = Arrays.asList(1);
// Map<Integer, Boolean> map1 = reqIds.stream().collect(Collectors.toMap(Function.identity(), item -> reqs.contains(item)));
// Map<Integer, Boolean> map2 = reqIds.stream().collect(Collectors.toMap(Function.identity(), reqs::contains));
//
// log.debug("Map Size {}",11+20);
//
// log.debug("Map Size {}", map2);
//
//
// List<Integer> shiftIds = Arrays.asList(1, 2);
// Map<Integer, Boolean> shiftIdMaps = new HashMap<Integer, Boolean>();
// shiftIdMaps.put(1, Boolean.TRUE);
// List<Integer> 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));
}
}

View File

@ -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 = (" <xml>\n" +
" <ToUserName><![CDATA[toUser]]></ToUserName>\n" +
" <FromUserName><![CDATA[fromUser]]></FromUserName>\n" +
" <CreateTime>1348831860</CreateTime>\n" +
" <MsgType><![CDATA[text]]></MsgType>\n" +
" <Content><![CDATA[this is a test - 您好]]></Content>\n" +
" <MsgId>1234567890123456</MsgId>\n" +
" <MsgDataId>xxxx</MsgDataId>\n" +
" <Idx>xxxx</Idx>\n" +
"</xml>");
}
@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);
}
}
}

View File

@ -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

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" ?>
<configuration debug="true">
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned by default the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<!-- FILE-DEBUG -->
<appender name="FILE-DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<prudent>true</prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>/var/log/usreio/%d{yyyy-MM-dd}/usreio-debug.log</fileNamePattern>
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<append>true</append>
<immediateFlush>true</immediateFlush>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- FILE-ERROR -->
<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<prudent>true</prudent>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>/var/log/usreio/%d{yyyy-MM-dd}/usreio-error.log</fileNamePattern>
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<append>true</append>
<immediateFlush>true</immediateFlush>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- LOGGER -->
<logger name="com.ossez" level="DEBUG"/>
<logger name="org.apache" level="INFO"/>
<logger name="org.mariadb" level="INFO"/>
<logger name="org.hibernate" level="INFO"/>
<logger name="org.springframework" level="INFO"/>
<!-- ROOT AND APPENDER -->
<root level="debug">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE-DEBUG"/>
<appender-ref ref="FILE-ERROR"/>
</root>
</configuration>