Compare commits
No commits in common. "acb8a77c5302af4c5729d8f4be34f7755775bb4c" and "cca6901cc6534057992c2464fd8c81506e24cb6e" have entirely different histories.
acb8a77c53
...
cca6901cc6
39
.gitignore
vendored
39
.gitignore
vendored
@ -1,39 +0,0 @@
|
|||||||
target/
|
|
||||||
!.mvn/wrapper/maven-wrapper.jar
|
|
||||||
!**/src/main/**/target/
|
|
||||||
!**/src/test/**/target/
|
|
||||||
.kotlin
|
|
||||||
|
|
||||||
### IntelliJ IDEA ###
|
|
||||||
.idea/modules.xml
|
|
||||||
.idea/jarRepositories.xml
|
|
||||||
.idea/compiler.xml
|
|
||||||
.idea/libraries/
|
|
||||||
*.iws
|
|
||||||
*.iml
|
|
||||||
*.ipr
|
|
||||||
|
|
||||||
### Eclipse ###
|
|
||||||
.apt_generated
|
|
||||||
.classpath
|
|
||||||
.factorypath
|
|
||||||
.project
|
|
||||||
.settings
|
|
||||||
.springBeans
|
|
||||||
.sts4-cache
|
|
||||||
|
|
||||||
### NetBeans ###
|
|
||||||
/nbproject/private/
|
|
||||||
/nbbuild/
|
|
||||||
/dist/
|
|
||||||
/nbdist/
|
|
||||||
/.nb-gradle/
|
|
||||||
build/
|
|
||||||
!**/src/main/**/build/
|
|
||||||
!**/src/test/**/build/
|
|
||||||
|
|
||||||
### VS Code ###
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
### Mac OS ###
|
|
||||||
.DS_Store
|
|
||||||
5
.idea/.gitignore
generated
vendored
5
.idea/.gitignore
generated
vendored
@ -1,5 +0,0 @@
|
|||||||
# 默认忽略的文件
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# 基于编辑器的 HTTP 客户端请求
|
|
||||||
/httpRequests/
|
|
||||||
6
.idea/encodings.xml
generated
6
.idea/encodings.xml
generated
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Encoding">
|
|
||||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
5
.idea/inspectionProfiles/profiles_settings.xml
generated
5
.idea/inspectionProfiles/profiles_settings.xml
generated
@ -1,5 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<settings>
|
|
||||||
<option name="PROJECT_PROFILE" />
|
|
||||||
</settings>
|
|
||||||
</component>
|
|
||||||
14
.idea/misc.xml
generated
14
.idea/misc.xml
generated
@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
|
||||||
<component name="MavenProjectsManager">
|
|
||||||
<option name="originalFiles">
|
|
||||||
<list>
|
|
||||||
<option value="$PROJECT_DIR$/pom.xml" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="15" project-jdk-type="JavaSDK">
|
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
62
pom.xml
62
pom.xml
@ -1,62 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
<groupId>org.shop</groupId>
|
|
||||||
<artifactId>crop</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.source>8</maven.compiler.source>
|
|
||||||
<maven.compiler.target>8</maven.compiler.target>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
|
||||||
<version>2.1.3.RELEASE</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<!-- Spring Web 依赖 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>1.18.30</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba</groupId>
|
|
||||||
<artifactId>fastjson</artifactId>
|
|
||||||
<version>1.2.83</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcprov-jdk18on</artifactId>
|
|
||||||
<version>1.77</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- MySQL 驱动 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>mysql</groupId>
|
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- MyBatis-Plus Starter -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.baomidou</groupId>
|
|
||||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
|
||||||
<version>3.5.6</version> <!-- 推荐使用最新稳定版 -->
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@ -1,128 +0,0 @@
|
|||||||
package com.tencent.wework;
|
|
||||||
|
|
||||||
/* sdk返回数据
|
|
||||||
typedef struct Slice_t {
|
|
||||||
char* buf;
|
|
||||||
int len;
|
|
||||||
} Slice_t;
|
|
||||||
|
|
||||||
typedef struct MediaData {
|
|
||||||
char* outindexbuf;
|
|
||||||
int out_len;
|
|
||||||
char* data;
|
|
||||||
int data_len;
|
|
||||||
int is_finish;
|
|
||||||
} MediaData_t;
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class Finance {
|
|
||||||
public native static long NewSdk();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化函数
|
|
||||||
* Return值=0表示该API调用成功
|
|
||||||
*
|
|
||||||
* @param [in] sdk NewSdk返回的sdk指针
|
|
||||||
* @param [in] corpid 调用企业的企业id,例如:wwd08c8exxxx5ab44d,可以在企业微信管理端--我的企业--企业信息查看
|
|
||||||
* @param [in] secret 聊天内容存档的Secret,可以在企业微信管理端--管理工具--聊天内容存档查看
|
|
||||||
* @return 返回是否初始化成功
|
|
||||||
* 0 - 成功
|
|
||||||
* !=0 - 失败
|
|
||||||
*/
|
|
||||||
public native static int Init(long sdk, String corpid, String secret);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拉取聊天记录函数
|
|
||||||
* Return值=0表示该API调用成功
|
|
||||||
*
|
|
||||||
* @param [in] sdk NewSdk返回的sdk指针
|
|
||||||
* @param [in] seq 从指定的seq开始拉取消息,注意的是返回的消息从seq+1开始返回,seq为之前接口返回的最大seq值。首次使用请使用seq:0
|
|
||||||
* @param [in] limit 一次拉取的消息条数,最大值1000条,超过1000条会返回错误
|
|
||||||
* @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081
|
|
||||||
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
|
|
||||||
* @param [out] chatDatas 返回本次拉取消息的数据,slice结构体.内容包括errcode/errmsg,以及每条消息内容。
|
|
||||||
* @return 返回是否调用成功
|
|
||||||
* 0 - 成功
|
|
||||||
* !=0 - 失败
|
|
||||||
*/
|
|
||||||
public native static int GetChatData(long sdk, long seq, long limit, String proxy, String passwd, long timeout, long chatData);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拉取媒体消息函数
|
|
||||||
* Return值=0表示该API调用成功
|
|
||||||
*
|
|
||||||
* @param [in] sdk NewSdk返回的sdk指针
|
|
||||||
* @param [in] sdkFileid 从GetChatData返回的聊天消息中,媒体消息包括的sdkfileid
|
|
||||||
* @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081
|
|
||||||
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
|
|
||||||
* @param [in] indexbuf 媒体消息分片拉取,需要填入每次拉取的索引信息。首次不需要填写,默认拉取512k,后续每次调用只需要将上次调用返回的outindexbuf填入即可。
|
|
||||||
* @param [out] media_data 返回本次拉取的媒体数据.MediaData结构体.内容包括data(数据内容)/outindexbuf(下次索引)/is_finish(拉取完成标记)
|
|
||||||
* @return 返回是否调用成功
|
|
||||||
* 0 - 成功
|
|
||||||
* !=0 - 失败
|
|
||||||
*/
|
|
||||||
public native static int GetMediaData(long sdk, String indexbuf, String sdkField, String proxy, String passwd, long timeout, long mediaData);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param [in] encrypt_key, getchatdata返回的encrypt_key
|
|
||||||
* @param [in] encrypt_msg, getchatdata返回的content
|
|
||||||
* @param [out] msg, 解密的消息明文
|
|
||||||
* @return 返回是否调用成功
|
|
||||||
* 0 - 成功
|
|
||||||
* !=0 - 失败
|
|
||||||
* @brief 解析密文
|
|
||||||
*/
|
|
||||||
public native static int DecryptData(long sdk, String encrypt_key, String encrypt_msg, long msg);
|
|
||||||
|
|
||||||
public native static void DestroySdk(long sdk);
|
|
||||||
|
|
||||||
public native static long NewSlice();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
* @brief 释放slice,和NewSlice成对使用
|
|
||||||
*/
|
|
||||||
public native static void FreeSlice(long slice);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return 内容
|
|
||||||
* @brief 获取slice内容
|
|
||||||
*/
|
|
||||||
public native static String GetContentFromSlice(long slice);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return 内容
|
|
||||||
* @brief 获取slice内容长度
|
|
||||||
*/
|
|
||||||
public native static int GetSliceLen(long slice);
|
|
||||||
|
|
||||||
public native static long NewMediaData();
|
|
||||||
|
|
||||||
public native static void FreeMediaData(long mediaData);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return outindex
|
|
||||||
* @brief 获取mediadata outindex
|
|
||||||
*/
|
|
||||||
public native static String GetOutIndexBuf(long mediaData);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return data
|
|
||||||
* @brief 获取mediadata data数据
|
|
||||||
*/
|
|
||||||
public native static byte[] GetData(long mediaData);
|
|
||||||
|
|
||||||
public native static int GetIndexLen(long mediaData);
|
|
||||||
|
|
||||||
public native static int GetDataLen(long mediaData);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return 1完成、0未完成
|
|
||||||
* @brief 判断mediadata是否结束
|
|
||||||
*/
|
|
||||||
public native static int IsMediaDataFinish(long mediaData);
|
|
||||||
|
|
||||||
static {
|
|
||||||
System.loadLibrary("WeWorkFinanceSdk");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
package org.shop.crop;
|
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author god23bin
|
|
||||||
*/
|
|
||||||
@SpringBootApplication
|
|
||||||
public class Application {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(Application.class, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,114 +0,0 @@
|
|||||||
package org.shop.crop;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import com.tencent.wework.Finance;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.shop.crop.dto.BaseMessageDto;
|
|
||||||
import org.shop.crop.dto.ChatData;
|
|
||||||
import org.shop.crop.dto.Message;
|
|
||||||
import org.shop.crop.dto.MessagePullResponse;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.core.io.ClassPathResource;
|
|
||||||
import org.springframework.util.StreamUtils;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@RestController
|
|
||||||
public class CropController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
Long sdk;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Environment environment; // nul
|
|
||||||
|
|
||||||
@GetMapping("/")
|
|
||||||
public String index() {
|
|
||||||
return "Hello, World!";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/crop/chatData")
|
|
||||||
private List<Message> chatData(Long startSeq) throws IOException {
|
|
||||||
long limit = 1000;
|
|
||||||
long slice = Finance.NewSlice();
|
|
||||||
int ret = Finance.GetChatData(sdk, startSeq, limit, "", "", 1000, slice);
|
|
||||||
if (ret != 0) {
|
|
||||||
System.out.println("调用sdk拉取消息接口失败,失败消息为 ret = " + ret);
|
|
||||||
Finance.FreeSlice(slice);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String contentResult = Finance.GetContentFromSlice(slice);
|
|
||||||
log.info("内容字符串" + contentResult);
|
|
||||||
return decodeChatData(contentResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解密chatData数据
|
|
||||||
*
|
|
||||||
* @param contentResult 拉取到的JSON原文
|
|
||||||
*/
|
|
||||||
public List<Message> decodeChatData(String contentResult) throws IOException {
|
|
||||||
// 1.基础信息解析
|
|
||||||
List<Message> messageList = new ArrayList<>();
|
|
||||||
MessagePullResponse messagePullResponse = JSON.parseObject(contentResult, MessagePullResponse.class);
|
|
||||||
if (messagePullResponse == null || messagePullResponse.getChatdata() == null) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
List<ChatData> chatdataList = messagePullResponse.getChatdata();
|
|
||||||
// 2.解密数据
|
|
||||||
ClassPathResource resource = new ClassPathResource("private_key.pem");
|
|
||||||
if (!resource.exists()) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
String privateKey = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
|
|
||||||
for (ChatData chatData : chatdataList) {
|
|
||||||
try {
|
|
||||||
// 解密ChatData数据
|
|
||||||
String plainTextJson = decrypt(chatData, privateKey);
|
|
||||||
BaseMessageDto messageDto = JSON.parseObject(plainTextJson, BaseMessageDto.class);
|
|
||||||
// 转换dto数据到entity
|
|
||||||
Message message = messageDto.convertToMessage();
|
|
||||||
message.setSeq(chatData.getSeq());
|
|
||||||
message.setOriginContent(plainTextJson);
|
|
||||||
messageList.add(message);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("解密失败{}", e.getMessage());
|
|
||||||
// 收集失败情况数据
|
|
||||||
e.printStackTrace();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4.保存消息和失败任务
|
|
||||||
return messageList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解密数据
|
|
||||||
*
|
|
||||||
* @param chatData 待解密数据
|
|
||||||
* @param privateKeyStr 私钥字符串
|
|
||||||
* @return 解密后的原文
|
|
||||||
*/
|
|
||||||
private String decrypt(ChatData chatData, String privateKeyStr) throws Exception {
|
|
||||||
// 1.解密EncryptRandomKey
|
|
||||||
String randomKey = EncodeUtils.decryptRandomKey(chatData.getEncryptRandomKey(), privateKeyStr);
|
|
||||||
// 2.调用SDK方法解密密文数据
|
|
||||||
long msg = Finance.NewSlice();
|
|
||||||
Finance.DecryptData(sdk, randomKey, chatData.getEncryptChatMsg(), msg);
|
|
||||||
String plaintext = Finance.GetContentFromSlice(msg);
|
|
||||||
Finance.FreeSlice(msg);
|
|
||||||
return plaintext;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
package org.shop.crop;
|
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.security.KeyFactory;
|
|
||||||
import java.security.PrivateKey;
|
|
||||||
import java.security.Security;
|
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
|
||||||
import java.security.spec.RSAPrivateCrtKeySpec;
|
|
||||||
import java.util.Base64;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 加解密工具
|
|
||||||
* @date 2024/11/21 9:22
|
|
||||||
*/
|
|
||||||
public class EncodeUtils {
|
|
||||||
|
|
||||||
public static PrivateKey getPrivateKey(String privKeyPEM) throws Exception {
|
|
||||||
String pem = privKeyPEM.trim();
|
|
||||||
// 清理头尾和空白
|
|
||||||
if (pem.contains("BEGIN PRIVATE KEY")) {
|
|
||||||
// PKCS#8 格式(使用 URL-safe Base64)
|
|
||||||
pem = pem
|
|
||||||
.replace("-----BEGIN PRIVATE KEY-----", "")
|
|
||||||
.replace("-----END PRIVATE KEY-----", "")
|
|
||||||
.replaceAll("\\s+", "");
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Invalid private key format");
|
|
||||||
}
|
|
||||||
System.out.println("Raw private key: " + pem);
|
|
||||||
|
|
||||||
// 关键:使用 url decoder!
|
|
||||||
byte[] derBytes = Base64.getDecoder().decode(pem);
|
|
||||||
|
|
||||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
||||||
|
|
||||||
// PKCS#8
|
|
||||||
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(derBytes);
|
|
||||||
return keyFactory.generatePrivate(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ 修复命名和字符集
|
|
||||||
public static String decryptRandomKey(String encryptedRandomKeyBase64, String privateKeyPem) throws Exception {
|
|
||||||
PrivateKey privateKey = getPrivateKey(privateKeyPem);
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
|
||||||
|
|
||||||
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedRandomKeyBase64);;
|
|
||||||
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
|
||||||
|
|
||||||
return new String(decryptedBytes, StandardCharsets.UTF_8); // 显式指定 UTF-8
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package org.shop.crop;
|
|
||||||
|
|
||||||
//TIP 要<b>运行</b>代码,请按 <shortcut actionId="Run"/> 或
|
|
||||||
// 点击装订区域中的 <icon src="AllIcons.Actions.Execute"/> 图标。
|
|
||||||
public class Main {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
//TIP 当文本光标位于高亮显示的文本处时按 <shortcut actionId="ShowIntentionActions"/>
|
|
||||||
// 查看 IntelliJ IDEA 建议如何修正。
|
|
||||||
System.out.printf("Hello and welcome!");
|
|
||||||
|
|
||||||
for (int i = 1; i <= 5; i++) {
|
|
||||||
//TIP 按 <shortcut actionId="Debug"/> 开始调试代码。我们已经设置了一个 <icon src="AllIcons.Debugger.Db_set_breakpoint"/> 断点
|
|
||||||
// 但您始终可以通过按 <shortcut actionId="ToggleLineBreakpoint"/> 添加更多断点。
|
|
||||||
System.out.println("i = " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package org.shop.crop;
|
|
||||||
|
|
||||||
import com.tencent.wework.Finance;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class MyConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public long sdk() {
|
|
||||||
System.out.println("Initializing SDK...");
|
|
||||||
long sdk = Finance.NewSdk();
|
|
||||||
int init = Finance.Init(
|
|
||||||
sdk,
|
|
||||||
"ww64f47cd0afc456a5",
|
|
||||||
"mEizahrSF6axdfWtSK_f73a3j6-sV02hhyGG7ogmTpM"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (init != 0) {
|
|
||||||
Finance.DestroySdk(sdk);
|
|
||||||
throw new RuntimeException("初始化sdk失败,失败消息为:ret = " + init);
|
|
||||||
}
|
|
||||||
return sdk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
package org.shop.crop.dao;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import com.baomidou.mybatisplus.annotation.*;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
import org.shop.crop.dto.Message;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@TableName("crop_message")
|
|
||||||
public class CropMessage {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键 ID(自增)
|
|
||||||
*/
|
|
||||||
@TableId(value = "id", type = IdType.AUTO)
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息唯一标识(全局 ID)
|
|
||||||
*/
|
|
||||||
@TableField("msg_id")
|
|
||||||
private String msgId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息动作(如 send, reply, delete)
|
|
||||||
*/
|
|
||||||
@TableField("action")
|
|
||||||
private String action;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送方 ID
|
|
||||||
*/
|
|
||||||
@TableField("from")
|
|
||||||
private String from; // 注意:'from' 是关键字,不能直接写,所以用注解指定
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 接收方列表(JSON 或逗号分隔)
|
|
||||||
*/
|
|
||||||
@TableField("tolist")
|
|
||||||
private String tolist;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 群聊消息的房间 ID
|
|
||||||
*/
|
|
||||||
@TableField("roomid")
|
|
||||||
private String roomid;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息序号(用于排序)
|
|
||||||
*/
|
|
||||||
@TableField("seq")
|
|
||||||
private Long seq;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息类型(如 text, image, voice)
|
|
||||||
*/
|
|
||||||
@TableField("msgtype")
|
|
||||||
private String msgtype;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解密后的明文内容(TEXT 类型)
|
|
||||||
*/
|
|
||||||
@TableField("content")
|
|
||||||
private String content;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息发送时间
|
|
||||||
*/
|
|
||||||
@TableField("msgtime")
|
|
||||||
private LocalDateTime msgtime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息状态(是否已处理)
|
|
||||||
*/
|
|
||||||
@TableField("status")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建时间(自动填充)
|
|
||||||
*/
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
private LocalDateTime createdTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 逻辑删除标志(0:正常,1:已删除)
|
|
||||||
*/
|
|
||||||
@TableLogic
|
|
||||||
@TableField("is_deleted")
|
|
||||||
private Integer isDeleted;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建时间(备用字段,可选)
|
|
||||||
*/
|
|
||||||
@TableField("gmt_created")
|
|
||||||
private LocalDateTime gmtCreated;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改时间(自动填充)
|
|
||||||
*/
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
||||||
private LocalDateTime gmtModified;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
package org.shop.crop.dto;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import com.alibaba.fastjson.annotation.JSONField;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 拉取基础信息dto
|
|
||||||
* @date 2024/11/21 17:50
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class BaseMessageDto {
|
|
||||||
/**
|
|
||||||
* 消息id,消息的唯一标识
|
|
||||||
*/
|
|
||||||
@JSONField(name = "msgid")
|
|
||||||
private String msgId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息动作
|
|
||||||
*/
|
|
||||||
@JSONField(name = "action")
|
|
||||||
private String action;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息发送方id
|
|
||||||
*/
|
|
||||||
@JSONField(name = "from")
|
|
||||||
private String fromId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息接收方列表
|
|
||||||
*/
|
|
||||||
@JSONField(name = "tolist")
|
|
||||||
private List<String> toList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 群聊消息的id
|
|
||||||
*/
|
|
||||||
@JSONField(name = "roomid")
|
|
||||||
private String roomId;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息类型
|
|
||||||
*/
|
|
||||||
@JSONField(name = "msgtype")
|
|
||||||
private String msgType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息发送的时间
|
|
||||||
*/
|
|
||||||
@JSONField(name = "msgtime")
|
|
||||||
private Long msgTime;
|
|
||||||
|
|
||||||
// getter setter
|
|
||||||
|
|
||||||
public Message convertToMessage(){
|
|
||||||
Message message = new Message();
|
|
||||||
message.setMsgId(this.msgId);
|
|
||||||
message.setAction(this.action);
|
|
||||||
message.setFromId(this.fromId);
|
|
||||||
message.setMsgTime(this.msgTime);
|
|
||||||
message.setMsgType(this.msgType);
|
|
||||||
message.setRoomId(this.roomId);
|
|
||||||
// id数组转为字符串
|
|
||||||
message.setToList(JSON.toJSONString(this.toList));
|
|
||||||
// 格式化时间
|
|
||||||
if(this.getMsgTime() != null){
|
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");;
|
|
||||||
LocalDateTime dateTime = LocalDateTime.ofInstant(
|
|
||||||
Instant.ofEpochSecond(this.getMsgTime()),
|
|
||||||
ZoneId.systemDefault()
|
|
||||||
);
|
|
||||||
String timeStr=dateTime.format(formatter);
|
|
||||||
message.setMsgTimeStr(timeStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package org.shop.crop.dto;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class ChatData {
|
|
||||||
private Long seq;
|
|
||||||
private String msgid;
|
|
||||||
@JsonProperty("publickey_ver")
|
|
||||||
private int publickeyVer;
|
|
||||||
@JsonProperty("encrypt_random_key")
|
|
||||||
private String encryptRandomKey;
|
|
||||||
@JsonProperty("encrypt_chat_msg")
|
|
||||||
private String encryptChatMsg;
|
|
||||||
|
|
||||||
// Getters and Setters
|
|
||||||
}
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
package org.shop.crop.dto;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 消息基础信息
|
|
||||||
* @date 2024/11/21 10:46
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class Message {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自增主键
|
|
||||||
*/
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息id,消息的唯一标识
|
|
||||||
*/
|
|
||||||
private String msgId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息动作
|
|
||||||
*/
|
|
||||||
private String action;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息发送方id
|
|
||||||
*/
|
|
||||||
private String fromId;
|
|
||||||
/**
|
|
||||||
* 消息发送方群名称
|
|
||||||
*/
|
|
||||||
private String fromNickName;
|
|
||||||
/**
|
|
||||||
* 消息发送方账户名称
|
|
||||||
*/
|
|
||||||
private String fromName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息接收方列表
|
|
||||||
*/
|
|
||||||
private String toList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 群聊消息的id
|
|
||||||
*/
|
|
||||||
private String roomId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息序号
|
|
||||||
*/
|
|
||||||
private Long seq;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息类型
|
|
||||||
*/
|
|
||||||
private String msgType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解密后的明文消息内容
|
|
||||||
*/
|
|
||||||
private String originContent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息发送的时间
|
|
||||||
*/
|
|
||||||
private Long msgTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息发送的时间(格式化)
|
|
||||||
*/
|
|
||||||
private String msgTimeStr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息状态(是否被处理)
|
|
||||||
*/
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
// Getters and Setters
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
package org.shop.crop.dto;
|
|
||||||
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.List;
|
|
||||||
@Data
|
|
||||||
public class MessagePullResponse {
|
|
||||||
private int errcode;
|
|
||||||
private String errmsg;
|
|
||||||
private List<ChatData> chatdata;
|
|
||||||
|
|
||||||
// Getters and Setters
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package org.shop.crop.mapper;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
import org.shop.crop.dao.CropMessage;
|
|
||||||
|
|
||||||
@Mapper
|
|
||||||
public interface CropMessageMapper extends BaseMapper<CropMessage> {
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
server.port=8085
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
spring:
|
|
||||||
datasource:
|
|
||||||
url: jdbc:mysql://121.199.65.65:3306/shop?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf-8
|
|
||||||
username: sktod_test
|
|
||||||
password: JlZOLKtvma8Z19XF
|
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
|
||||||
|
|
||||||
mybatis-plus:
|
|
||||||
mapper-locations: classpath:mapper/*.xml
|
|
||||||
type-aliases-package: com.example.demo.entity
|
|
||||||
configuration:
|
|
||||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印SQL
|
|
||||||
global-config:
|
|
||||||
db-config:
|
|
||||||
id-type: auto
|
|
||||||
logic-delete-value: 1
|
|
||||||
logic-not-delete-value: 0
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDbQp/SsUQgkhbX
|
|
||||||
tzdl/IJVkX9eYD4Qusd8nBhCRYkN6VfQpONX1r9qpvQOkXy0D0FDMpJnRnvDZLQ3
|
|
||||||
INduo8caj/101DxK6NHc5mYIJ9U2G561JyvDtkiS68qL1bepCK729lZSnvZBs6jr
|
|
||||||
A4ARN0DTtiFsjqK26oZXP4NqnfI8lYyMjaEvXHpQfA7+MI6LAyQAvC0KtM1681aM
|
|
||||||
+DAlsma88FRaPSEKvfTkWKvKgZUrfCUuDZscvczROlgNpEYHL4tNVPhQxaLOEB9m
|
|
||||||
iTfsAIVLdadJBVbhUq3qsTGBKa+Bo3XKMgkHVQl9KJaPv3r4SJ8cyv8mWCp+8VQ0
|
|
||||||
C2Mmw9rLAgMBAAECggEAODiWq5s5mVJsWgbIRTXgo5lJvATYlUiXYzvROpkC4hbN
|
|
||||||
phnJk5nkfi/uD5g9jhwFQ3pBsQqRLJJzZVld9Cg5ovV964mKJjkZqtdHHVs9YADo
|
|
||||||
CpJPNgFVDZs5Ve7Ih6bK2ldi3g+VnFY5f31nxsJQtJiUbHYMgfOT2+ZUx69VUDQd
|
|
||||||
AAB1D/V0SqbIBO9+MTInkfUeN91p+HPWNyLssMDOn9LWmD6N2irzpS6Uo47vpGT2
|
|
||||||
lyFUcTZ8iNebebLdRPTmv1wx7mziPc0CVjsKhAwSDwZJHdlUOiWEipDnJ2Kggy6i
|
|
||||||
T9tl+XpfDU3ymel7mg6MjTHErSA42K7IM2cYHYx4JQKBgQD1qgJndwxtF6NOMW6+
|
|
||||||
zDYQ454F3iuc3U6N7jNx5T4MxkR5TfIlwQypYEpxMzYI+mJUmrBebTM+eoC7i1QG
|
|
||||||
oOA+r/5DBsK8MTK/W9uyAyMlH+dEmvpkxWIKxS80U63m9ZuqAoXmSnWTcERD2nTg
|
|
||||||
eKnbPHJ23cZM+eSM1FzZKR6jzQKBgQDkfDmpXR0wZ0VwBpm2sKqO1cgZ3BVC9adN
|
|
||||||
ZngWl1OVvWZMY0jTEwVKYvDmBGpLX6eFk8D+8v+gKkkG87m8b4A6UnrJFXjXDGOf
|
|
||||||
cSitwLq7Xfuv97M2Pl9sfkMRs3w6CxZn0IM2SuMAqXeTlZiEhdk9P+lbQs4lkBXC
|
|
||||||
0ta9xtMQ9wKBgAFhIwJRuNAkAda+kFCh9OvDW2/M/5Gx7G7/l2pcTyzjMB8+QM3V
|
|
||||||
d6y7za81Cmiif0raU4M0OcVwCqkC70XaQWgYtOTLdOx5mj9Y1LL7MYdT1oicFiva
|
|
||||||
r+I/mTRCBAf3+RfLS9UvNdnOF5QJ9f4Mr2d7v2jLdgGYpZ/k0WCmynVBAoGBAL9i
|
|
||||||
Kq5pl1yG9EvMy46SVpsECPNYPNr0h2m2zhomMVY46mpLs6FRylmvnJce1aZC/kBO
|
|
||||||
LheflW0kXj0bg9WKE/9GPSEYAjsnXn8cOvWnfQIazApuUce64RUwgZ9fF0xLIz5c
|
|
||||||
Erw0aAaS7N1LLhC7SOccFKxjvecK1J93GXanBv6rAoGBAMtwLcBLHqbzefawkkow
|
|
||||||
UoFdz64nM5X47mFVyeVeIW85rUV6lLS2m1WtLYA12qRZ3nx4ls268P9CUYAH7Vh2
|
|
||||||
m/NWH3UJvNbYR1Z3SPs2qUfTVQ4cJC23bp0ij4J2GMBNGA8m+RTrQK7gTSofvG3d
|
|
||||||
LzNelpso5YqSOUw3nfTiNLBn
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user