企业解决方案七-个人微信动态库实现消息发送与消息24小时监听与大模型智能提效解析存储

增加好友、群检索功能,方便针对性的回访客户,搜索+快速选择群发沟通~

一、项目背景与需求分析
在日常的微信运营工作中,经常需要对多个好友或群聊进行批量消息发送,例如活动通知、节日祝福、重要公告等场景。传统的逐一手动发送方式效率低下,且容易遗漏。本文介绍如何构建一套完整的微信管理工具,实现好友/群组数据的可视化管理以及批量消息的快速发送。
1.1 核心功能需求
-
好友列表管理:展示所有好友信息,支持多选、全选、清空
-
群聊列表管理:展示所有群组信息,支持多选、全选、清空
-
批量消息发送:向选中的多个会话(好友或群聊)同时发送消息
-
数据同步:支持好友/群组信息的批量新增与更新
1.2 技术选型
| 层级 | 技术栈 |
|---|---|
| 后端框架 | Spring Boot + MyBatis-Plus |
| 前端框架 | 原生HTML/CSS/JavaScript |
| 数据库 | MySQL |
| 微信SDK | 基于微信个人号/企业微信SDK |
| JSON处理 | Gson + Jackson |
二、后端架构设计
2.1 项目结构
com.black
├── controller
│ └── BigController.java # 核心控制器
├── mapper
│ ├── FriendMapper.java # 好友数据访问
│ └── Group1Mapper.java # 群聊数据访问
├── pojo
│ ├── Friend.java # 好友实体
│ ├── Group1.java # 群聊实体
│ └── Msg.java # 消息实体
├── util
│ └── Res.java # 统一响应结果
└── step
└── Step3_SendText.java # 微信消息发送封装
2.2 数据库设计
好友表(friend)
CREATE TABLE friend (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id VARCHAR(64) NOT NULL COMMENT '微信用户ID',
nick_name VARCHAR(100) COMMENT '昵称',
remark VARCHAR(100) COMMENT '备注名',
create_time DATETIME,
update_time DATETIME
);
群聊表(group1)
CREATE TABLE group1 (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
room_id VARCHAR(64) NOT NULL COMMENT '群聊房间ID',
nick_name VARCHAR(100) COMMENT '群名称',
remark VARCHAR(100) COMMENT '群备注',
create_time DATETIME,
update_time DATETIME
);
2.3 核心控制器实现
2.3.1 好友数据批量同步
@PostMapping("/insert_friend")
public void insert_friend(@RequestBody List<Friend> insertFriendList) {
// 查询现有数据
List<Friend> existFriendList = friendMapper.selectList(null);
Map<String, Friend> existFriendMap = existFriendList.stream()
.collect(Collectors.toMap(Friend::getUserId, Function.identity()));
// 分离新增和更新
List<Friend> newFriendList = new ArrayList<>();
List<Friend> updateFriendList = new ArrayList<>();
for (Friend friend : insertFriendList) {
if (existFriendMap.containsKey(friend.getUserId())) {
Friend existFriend = existFriendMap.get(friend.getUserId());
existFriend.setRemark(friend.getRemark());
updateFriendList.add(existFriend);
} else {
newFriendList.add(friend);
}
}
// 批量操作
if (!newFriendList.isEmpty()) {
friendMapper.insertBatchFriend(newFriendList);
}
if (!updateFriendList.isEmpty()) {
friendMapper.updateBatchById(updateFriendList);
}
}
设计亮点:
-
使用
Collectors.toMap构建索引Map,时间复杂度O(n) -
分离新增/更新逻辑,避免重复操作
-
批量操作提升数据库性能
2.3.2 群聊数据同步
群聊的同步逻辑与好友完全一致,体现了代码的复用性设计:
@PostMapping("/insert_group1")
public void insert_group1(@RequestBody List<Group1> insertGroup1List) {
// 相同的模式:查询现有 -> 比对 -> 分离 -> 批量操作
List<Group1> existGroup1List = group1Mapper.selectList(null);
Map<String, Group1> existGroup1Map = existGroup1List.stream()
.collect(Collectors.toMap(Group1::getRoomId, Function.identity()));
// ... 后续逻辑与好友相同
}
2.3.3 消息发送接口
@PostMapping("/send_text")
public void send_text(@RequestBody Msg msg) throws Exception {
for (String tempUserOrRoomId : msg.getUserOrRoomIdList()) {
Map<String, Object> result = sendTextMsg(tempUserOrRoomId, msg.getContent());
log.info("发送结果: userOrRoomId={}, result={}", tempUserOrRoomId, result);
}
}
2.3.4 微信消息接收处理
@PostMapping("/receive_python_msg")
public void receive_python_msg(@RequestBody Object pythonMsg) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(pythonMsg);
TextMsgJsonParse textMsgJsonParse = gson.fromJson(jsonStr, TextMsgJsonParse.class);
int eventType = textMsgJsonParse.event_type;
// 处理私聊(2004)和群聊(2000)消息
if (eventType == 2004 || eventType == 2000) {
long createTime = textMsgJsonParse.createTime;
String tempTime = TimestampConverter.doWork(createTime);
// 根据类型查询用户/群信息
// 可接入智能回复逻辑
}
}
2.4 统一响应封装
public class Res {
private String code;
private String message;
private Object object;
public static Res success(Object data) {
Res res = new Res();
res.setCode("200");
res.setMessage("success");
res.setObject(data);
return res;
}
public static Res error(String message) {
Res res = new Res();
res.setCode("500");
res.setMessage(message);
return res;
}
}
三、前端界面实现
3.1 布局设计
采用左右双栏布局,左侧展示好友列表,右侧展示群聊列表,底部为消息发送区域:
.dashboard {
width: 1400px;
height: 90vh;
background: white;
border-radius: 24px;
display: flex;
flex-direction: column;
}
.main-content {
display: flex;
flex: 1;
gap: 1px;
background: #eef2f6;
}
.friends-panel, .groups-panel {
flex: 1;
background: white;
display: flex;
flex-direction: column;
}
3.2 数据模型
let friends = []; // 好友列表 let groups = []; // 群聊列表 let selectedFriends = new Set(); // 选中好友ID集合 let selectedGroups = new Set(); // 选中群聊ID集合
使用Set数据结构存储选中项,具有以下优势:
-
自动去重
-
O(1)时间复杂度的增删查
-
与ES6语法完美兼容
3.3 API接口调用
获取好友列表
async function fetchFriends() {
const response = await fetch(`${API_BASE}/select_friend`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
});
const resData = await response.json();
// 兼容多种返回格式
let friendList = resData.object || resData.data || resData;
friends = friendList.map(f => ({
userId: f.userId || f.user_id,
nickName: f.nickName || f.nickname,
remark: f.remark || ''
})).filter(f => f.userId);
renderFriends();
}
批量发送消息
async function batchSendMessage() {
const content = document.getElementById('messageContent').value.trim();
const userOrRoomIdList = [...selectedFriends, ...selectedGroups];
const payload = {
userOrRoomIdList: userOrRoomIdList,
content: content
};
const response = await fetch(`${API_BASE}/send_text`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
}
3.4 列表渲染与交互
function renderFriends() {
let html = '';
friends.forEach(friend => {
const isSelected = selectedFriends.has(friend.userId);
html += `
<div class="contact-item ${isSelected ? 'selected' : ''}"
data-type="friend" data-id="${escapeHtml(friend.userId)}">
<div class="avatar">${escapeHtml(avatarLetter)}</div>
<div class="info">
<div class="name">${escapeHtml(displayName)}</div>
<div class="remark">${escapeHtml(remarkText)}</div>
</div>
<div class="checkbox-indicator"></div>
</div>
`;
});
container.innerHTML = html;
// 事件委托或逐个绑定
container.querySelectorAll('.contact-item').forEach(el => {
el.addEventListener('click', () => toggleSelection(el));
});
}
3.5 选中状态管理
function toggleFriendSelection(userId) {
if (selectedFriends.has(userId)) {
selectedFriends.delete(userId);
} else {
selectedFriends.add(userId);
}
renderFriends(); // 重新渲染
updateSelectionPreview(); // 更新预览区
}
function updateSelectionPreview() {
const totalSelected = selectedFriends.size + selectedGroups.size;
document.getElementById('selectedCount').innerText = totalSelected;
// 构建详情显示
const selectedFriendNames = [...selectedFriends].map(uid => {
const f = friends.find(fr => fr.userId === uid);
return f?.remark || f?.nickName || uid;
});
// 更新DOM...
}
四、关键技术点解析
4.1 跨域问题解决
前后端分离架构需要处理CORS:
@Configuration
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowCredentials(true);
}
};
}
}
4.2 MyBatis-Plus批量操作
自定义批量插入方法:
@Mapper
public interface FriendMapper extends BaseMapper<Friend> {
void insertBatchFriend(@Param("list") List<Friend> list);
}
对应的XML:
<insert id="insertBatchFriend">
INSERT INTO friend (user_id, nick_name, remark) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.userId}, #{item.nickName}, #{item.remark})
</foreach>
</insert>
4.3 微信消息协议解析
微信回调消息格式:
{
"event_type": 2004,
"event_desc": "私聊消息",
"content": {
"String": "你好,这是一条测试消息"
},
"fromUserName": {
"String": "wxid_xxxx"
},
"createTime": 1678901234567
}
使用嵌套静态类解析:
static class TextMsgJsonParse {
int event_type;
TextMsgContent content;
TextMsgFromUserName fromUserName;
long createTime;
}
static class TextMsgContent {
String String; // 注意字段名
}
4.4 状态提示与用户体验
function showToast(msg, isError = false) {
const toastEl = document.getElementById('toast');
toastEl.textContent = msg;
toastEl.style.backgroundColor = isError ? '#b91c1c' : '#1e293b';
toastEl.style.opacity = '1';
setTimeout(() => {
toastEl.style.opacity = '0';
}, 2500);
}
五、部署与运行
5.1 后端配置
# application.yml
server:
port: 5000
spring:
datasource:
url: jdbc:mysql://localhost:3306/wechat_db
username: root
password: 123456
logging:
level:
com.black: DEBUG
5.2 前端部署
直接将HTML文件放入Spring Boot的static目录,或单独使用Nginx部署。
5.3 启动命令
# 后端 mvn spring-boot:run # 前端(如使用live-server) npx live-server --port=8080
六、优化建议与扩展
6.1 性能优化
-
虚拟滚动:当好友/群聊数量超过1000时,使用虚拟列表减少DOM节点
-
防抖节流:搜索输入时使用debounce减少请求
-
请求合并:批量操作时合并多个请求
6.2 功能扩展
-
消息模板:预定义常用消息模板,支持变量替换
-
定时发送:集成Quartz实现定时批量发送
-
发送记录:记录每条消息的发送状态和回执
-
消息去重:防止短时间内向同一用户重复发送相同内容
-
智能回复:接入AI大模型实现自动回复
6.3 安全增强
-
添加JWT认证,防止接口被恶意调用
-
对敏感操作添加验证码
-
记录操作日志用于审计
-
限制单次发送的数量上限
七、踩坑记录
7.1 Jackson解析问题
当使用@RequestBody Object接收时,Jackson会将其解析为LinkedHashMap,内部嵌套结构也是Map,需要注意类型转换。
7.2 微信ID特殊字符
微信ID可能包含特殊字符,在HTML渲染时需要使用escapeHtml进行转义,防止XSS攻击。
7.3 批量操作事务
当批量插入和更新混合时,建议使用@Transactional确保数据一致性:
@Transactional(rollbackFor = Exception.class)
public void insert_friend(@RequestBody List<Friend> insertFriendList) {
// 操作逻辑
}
八、总结
本文完整实现了一套微信管理工具,涵盖后端API设计、前端界面开发、数据同步机制、批量消息发送等核心功能。系统采用Spring Boot + MyBatis-Plus提供稳定可靠的后端服务,使用原生JavaScript构建简洁高效的前端界面。
通过这套工具,运营人员可以快速完成批量消息发送任务,大幅提升工作效率。代码结构清晰,易于扩展,可作为企业微信管理系统的参考实现。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)