commit fa262e97f22f2de95d89fdd9849ce8ecd0d0a5d5 Author: 杨建炊 <924182103@qq.com> Date: Wed Sep 24 17:16:04 2025 +0800 feat: initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..480bdf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +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 \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..bf2de99 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..4140949 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..0eefe32 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..9e1b5e9 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..9661ac7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..bd6121b --- /dev/null +++ b/pom.xml @@ -0,0 +1,62 @@ + + + 4.0.0 + + org.shop + crop + 1.0-SNAPSHOT + + + 8 + 8 + UTF-8 + + + + org.springframework.boot + spring-boot-starter-parent + 2.1.3.RELEASE + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.projectlombok + lombok + 1.18.30 + provided + + + com.alibaba + fastjson + 1.2.83 + + + org.bouncycastle + bcprov-jdk18on + 1.77 + + + + mysql + mysql-connector-java + runtime + + + + + com.baomidou + mybatis-plus-boot-starter + 3.5.6 + + + + + + \ No newline at end of file diff --git a/src/main/java/com/tencent/wework/Finance.java b/src/main/java/com/tencent/wework/Finance.java new file mode 100644 index 0000000..e72e221 --- /dev/null +++ b/src/main/java/com/tencent/wework/Finance.java @@ -0,0 +1,128 @@ +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"); + } +} \ No newline at end of file diff --git a/src/main/java/org/shop/crop/Application.java b/src/main/java/org/shop/crop/Application.java new file mode 100644 index 0000000..e62c2dc --- /dev/null +++ b/src/main/java/org/shop/crop/Application.java @@ -0,0 +1,15 @@ +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); + } +} \ No newline at end of file diff --git a/src/main/java/org/shop/crop/CropController.java b/src/main/java/org/shop/crop/CropController.java new file mode 100644 index 0000000..d05dc14 --- /dev/null +++ b/src/main/java/org/shop/crop/CropController.java @@ -0,0 +1,114 @@ +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 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 decodeChatData(String contentResult) throws IOException { + // 1.基础信息解析 + List messageList = new ArrayList<>(); + MessagePullResponse messagePullResponse = JSON.parseObject(contentResult, MessagePullResponse.class); + if (messagePullResponse == null || messagePullResponse.getChatdata() == null) { + return Collections.emptyList(); + } + List 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; + } + + +} diff --git a/src/main/java/org/shop/crop/EncodeUtils.java b/src/main/java/org/shop/crop/EncodeUtils.java new file mode 100644 index 0000000..ca576a5 --- /dev/null +++ b/src/main/java/org/shop/crop/EncodeUtils.java @@ -0,0 +1,55 @@ +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 + } + +} \ No newline at end of file diff --git a/src/main/java/org/shop/crop/Main.java b/src/main/java/org/shop/crop/Main.java new file mode 100644 index 0000000..1d7701d --- /dev/null +++ b/src/main/java/org/shop/crop/Main.java @@ -0,0 +1,17 @@ +package org.shop.crop; + +//TIP 要运行代码,请按 或 +// 点击装订区域中的 图标。 +public class Main { + public static void main(String[] args) { + //TIP 当文本光标位于高亮显示的文本处时按 + // 查看 IntelliJ IDEA 建议如何修正。 + System.out.printf("Hello and welcome!"); + + for (int i = 1; i <= 5; i++) { + //TIP 按 开始调试代码。我们已经设置了一个 断点 + // 但您始终可以通过按 添加更多断点。 + System.out.println("i = " + i); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/shop/crop/MyConfig.java b/src/main/java/org/shop/crop/MyConfig.java new file mode 100644 index 0000000..9f32ea5 --- /dev/null +++ b/src/main/java/org/shop/crop/MyConfig.java @@ -0,0 +1,26 @@ +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; + } +} diff --git a/src/main/java/org/shop/crop/dao/CropMessage.java b/src/main/java/org/shop/crop/dao/CropMessage.java new file mode 100644 index 0000000..1f3a955 --- /dev/null +++ b/src/main/java/org/shop/crop/dao/CropMessage.java @@ -0,0 +1,112 @@ +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; + + + +} diff --git a/src/main/java/org/shop/crop/dto/BaseMessageDto.java b/src/main/java/org/shop/crop/dto/BaseMessageDto.java new file mode 100644 index 0000000..292922d --- /dev/null +++ b/src/main/java/org/shop/crop/dto/BaseMessageDto.java @@ -0,0 +1,90 @@ +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 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; + } + +} diff --git a/src/main/java/org/shop/crop/dto/ChatData.java b/src/main/java/org/shop/crop/dto/ChatData.java new file mode 100644 index 0000000..6bd201b --- /dev/null +++ b/src/main/java/org/shop/crop/dto/ChatData.java @@ -0,0 +1,18 @@ +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 +} \ No newline at end of file diff --git a/src/main/java/org/shop/crop/dto/Message.java b/src/main/java/org/shop/crop/dto/Message.java new file mode 100644 index 0000000..103a378 --- /dev/null +++ b/src/main/java/org/shop/crop/dto/Message.java @@ -0,0 +1,81 @@ +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 +} \ No newline at end of file diff --git a/src/main/java/org/shop/crop/dto/MessagePullResponse.java b/src/main/java/org/shop/crop/dto/MessagePullResponse.java new file mode 100644 index 0000000..24bd74d --- /dev/null +++ b/src/main/java/org/shop/crop/dto/MessagePullResponse.java @@ -0,0 +1,15 @@ +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; + + // Getters and Setters +} \ No newline at end of file diff --git a/src/main/java/org/shop/crop/mapper/CropMessageMapper.java b/src/main/java/org/shop/crop/mapper/CropMessageMapper.java new file mode 100644 index 0000000..52c9c4e --- /dev/null +++ b/src/main/java/org/shop/crop/mapper/CropMessageMapper.java @@ -0,0 +1,9 @@ +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 { +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..a30a91f --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1 @@ +server.port=8085 \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..0eb3f73 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,17 @@ +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 \ No newline at end of file diff --git a/src/main/resources/private_key.pem b/src/main/resources/private_key.pem new file mode 100644 index 0000000..191a8ee --- /dev/null +++ b/src/main/resources/private_key.pem @@ -0,0 +1,28 @@ +-----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----- \ No newline at end of file diff --git a/src/main/resources/wechat.sdk/WeWorkFinanceSdk.dll b/src/main/resources/wechat.sdk/WeWorkFinanceSdk.dll new file mode 100644 index 0000000..4ce7286 Binary files /dev/null and b/src/main/resources/wechat.sdk/WeWorkFinanceSdk.dll differ diff --git a/src/main/resources/wechat.sdk/libWeWorkFinanceSdk_Java.so b/src/main/resources/wechat.sdk/libWeWorkFinanceSdk_Java.so new file mode 100644 index 0000000..d506486 Binary files /dev/null and b/src/main/resources/wechat.sdk/libWeWorkFinanceSdk_Java.so differ diff --git a/src/main/resources/wechat.sdk/libcrypto-3-x64.dll b/src/main/resources/wechat.sdk/libcrypto-3-x64.dll new file mode 100644 index 0000000..b1a6dbe Binary files /dev/null and b/src/main/resources/wechat.sdk/libcrypto-3-x64.dll differ diff --git a/src/main/resources/wechat.sdk/libcurl-x64.dll b/src/main/resources/wechat.sdk/libcurl-x64.dll new file mode 100644 index 0000000..8b79e41 Binary files /dev/null and b/src/main/resources/wechat.sdk/libcurl-x64.dll differ