企业解决方案二十-企微消息监听与房源、车源、救援信息提炼分析存储转化使用方案

📅 2026/7/13 23:07:43 👁️ 阅读次数 📝 编程学习
企业解决方案二十-企微消息监听与房源、车源、救援信息提炼分析存储转化使用方案

一、项目背景与技术选型

1.1 业务场景分析

在汽车销售与客户服务领域,企业微信已成为连接客户的重要渠道。销售人员每天需要处理大量客户咨询,其中包含大量潜在的购车需求信息。传统的人工处理方式存在以下痛点:

  • 消息量大:单个销售顾问每天可能接收数百条客户消息

  • 信息分散:购车意向、图片资料、联系方式分散在不同对话中

  • 响应滞后:无法第一时间识别高价值客户需求

  • 信息遗漏:重要信息可能被淹没在海量消息中

本项目通过监听企业微信消息,结合AI大模型和图像识别技术,实现客户购车意向的自动识别与车源信息提炼。

1.2 核心技术架构

┌─────────────────────────────────────────────────────────────────┐ │ 技术架构总览 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 企业微信客户端 ←→ Python监听服务 → Java SpringBoot后端 │ │ ↓ │ │ 消息解析与分类 │ │ ↓ │ │ ┌──────────┴──────────┐ │ │ ↓ ↓ │ │ 文本消息处理 图片消息处理 │ │ ↓ ↓ │ │ 大模型意图分析 OSS上传+图像识别 │ │ ↓ ↓ │ │ 信息整合与过滤 车源判定 │ │ ↓ │ │ 数据库存储+定时任务 │ │ │ └─────────────────────────────────────────────────────────────────┘

1.3 技术栈详述

技术组件选型用途说明
开发语言Java 8 / Python主逻辑/监听服务
Web框架Spring BootRESTful API服务
ORM框架MyBatis-Plus数据库操作简化
JSON处理Fastjson / Gson消息序列化
图像识别自研AI模型车源图片判定
大模型扣子智能体信息提炼与答复
文件存储阿里云OSS图片持久化
并发控制ReentrantReadWriteLock文件读写安全
定时任务Spring Scheduled数据同步刷新

二、核心功能模块详解

2.1 消息监听与解析模块

2.1.1 消息入口设计

消息监听入口通过/receive_python_msg接口接收来自Python监听服务的消息:

@PostMapping("/receive_python_msg") public void receive_python_msg(@RequestBody PythonMsg pythonMsg) throws Exception { String listenMsg = pythonMsg.getGet_internal_contacts_res(); // 解析JSON消息 JsonParseInnerFriend jsonParseInnerFriend = gson.fromJson(listenMsg, JsonParseInnerFriend.class); Integer type = jsonParseInnerFriend.type; // 根据消息类型分发处理 }
2.1.2 消息类型分类处理

企业微信消息包含多种类型,系统对不同类型的消息进行差异化处理:

类型码消息类型处理策略
11041文本消息直接提取文本内容,送入大模型分析
11042图片消息下载图片→上传OSS→图像识别判定车源
11046位置消息提取经纬度、地址信息
11078群信息变更同步更新群名称
2.1.3 图片处理完整链路

图片消息的处理是系统中的关键环节,涉及多个步骤:

case 11042: // 1. 生成唯一文件名并下载图片 String savePath = Constants.IMAGE_SAVE_PATH + "\\" + System.currentTimeMillis() + ".jpg"; Map<String, Object> result1 = downloadImage(1, 1, chatInfoJson.data.cdn.url, chatInfoJson.data.cdn.auth_key, chatInfoJson.data.cdn.aes_key, chatInfoJson.data.cdn.size, savePath); // 2. 上传到阿里云OSS Map<String, Object> result = uploadToOSS(savePath); tempWxInfo.setImageUrl((String) result.get("url")); // 3. 清理本地临时文件 File tempFile = new File(savePath); if (tempFile.delete()) { System.out.println("文件删除成功: " + savePath); } break;

2.2 信息缓存与持久化

2.2.1 内存缓存设计

系统使用Constants.WX_INFO_LIST作为消息的内存缓存,并配合文件持久化保证数据安全:

// 内存缓存 public static List<WxInfo> WX_INFO_LIST = new ArrayList<>(); // WxInfo数据结构 public class WxInfo { private String id; // 消息唯一ID private String sender; // 发送者 private String sendContent; // 发送内容 private String imageUrl; // 图片URL private String groupName; // 群名称 private long sendTime; // 发送时间 // getters/setters省略 }
2.2.2 文件读写锁实现

为保障文件操作线程安全,采用ReentrantReadWriteLock实现读写分离:

private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public static void appendToFile(WxInfo wxInfo) { lock.writeLock().lock(); try { List<WxInfo> existingList = loadFromFile(); existingList.add(wxInfo); writeFullArray(existingList); } finally { lock.writeLock().unlock(); } } public static List<WxInfo> loadFromFile() { lock.readLock().lock(); try { // 读取文件逻辑 } finally { lock.readLock().unlock(); } }
2.2.3 文件损坏恢复机制

为防止文件损坏导致数据丢失,实现了自动备份恢复机制:

private static void backupAndCreateNewFile() { try { File file = new File(FILE_PATH); if (file.exists()) { File backupFile = new File("wx_info_list_backup_" + System.currentTimeMillis() + ".txt"); file.renameTo(backupFile); System.out.println("已备份损坏的文件到: " + backupFile.getName()); } writeFullArray(new ArrayList<>()); } catch (IOException e) { System.err.println("备份文件失败: " + e.getMessage()); } }

2.3 消息合并与智能过滤

2.3.1 消息合并策略

系统实现了基于时间窗口和语义相似度的消息合并机制:

if (Constants.WX_INFO_LIST.size() > 300) { // 获取合并关系列表 List<MergeRelation> mergeRelations = integrateWxInfosWithRelation( Constants.WX_INFO_LIST ); for (MergeRelation relation : mergeRelations) { WxInfo wxInfo = relation.getMergedInfo(); // 处理合并后的信息 } }
2.3.2 车源信息判定

通过图像识别大模型判定图片是否为汽车或驾驶证:

String imageModelRes = Step6_IsCarOrNotSmart.SmartWork( UUID.randomUUID().toString(), tempImgUrl ); ImageModelResJson imageModelResJson = gson.fromJson( imageModelRes, ImageModelResJson.class ); if (imageModelResJson.aCarOrADrivingLicense.equals("是")) { tempTotalUrl.append(tempImgUrl).append(","); }
2.3.3 联系方式提取

通过正则匹配和AI分析,从文本中提取电话号码等联系信息:

if (Step7_PhoneNumberUtil.containsPhoneNumber(wxInfo.getSendContent()) || Step7_PhoneNumberUtil.containsPhoneNumber(wxInfo.getSender())) { // 构建完整信息并存储 String totalInfo = "群名称:" + wxInfo.getGroupName() + "。发送者:" + wxInfo.getSender() + "。\n"; totalInfo = totalInfo + "发送信息如下:\n" + wxInfo.getSendContent() + "。imgRul的值为:" + tempTotalUrl; // 调用信息提炼大模型 String uploadInfo = Step8_InfoExtractSmart.SmartWork( UUID.randomUUID().toString(), totalInfo ); }

2.4 数据同步与定时任务

2.4.1 好友列表同步
@PostMapping("/update_friend1_list") public Res update_friend1_list(@RequestBody List<Friend1> friend1List) { try { List<Friend1> mysqlExistFriend1List = friend1Mapper.selectList(null); Map<String, Friend1> mysqlMap = mysqlExistFriend1List.stream() .collect(Collectors.toMap(Friend1::getUserId, f -> f)); // 分离需要更新和新增的数据 Map<Boolean, List<Friend1>> partitioned = friend1List.stream() .collect(Collectors.partitioningBy( friend -> mysqlMap.containsKey(friend.getUserId()) )); // 批量更新 List<Friend1> toUpdate = partitioned.get(true).stream() .filter(friend -> { Friend1 exist = mysqlMap.get(friend.getUserId()); return !Objects.equals(friend.getNickName(), exist.getNickName()); }) .peek(friend -> friend.setId(mysqlMap.get(friend.getUserId()).getId())) .collect(Collectors.toList()); // 批量插入 List<Friend1> toInsert = partitioned.get(false); if (!toUpdate.isEmpty()) { for (Friend1 tempFriend1 : toUpdate) { friend1Mapper.updateById(tempFriend1); } } if (!toInsert.isEmpty()) { sendMapper.insertBatchFriend1(toInsert); } return Res.success(); } catch (Exception e) { e.printStackTrace(); return Res.error(); } }
2.4.2 定时任务配置
// 群信息同步 - 每12小时执行一次 @Scheduled(fixedRate = 30 * 720 * 60 * 1000) public void scheduledRefreshGroup() { try { Step3_GroupOnce.doWork(); System.out.println("恭喜,刷新信息成功,请继续操作!"); } catch (Exception e) { System.err.println("抱歉,刷新信息出现错误,请检查..."); e.printStackTrace(); } } // 好友信息同步 - 每10分钟执行一次 @Scheduled(fixedRate = 10 * 60 * 1000) public void scheduledRefresh() { try { Step1_Friend.doWork(); Step2_Friend.doWork(); System.out.println("恭喜,刷新信息成功,请继续操作!"); } catch (Exception e) { System.err.println("抱歉,刷新信息出现错误,请检查..."); e.printStackTrace(); } }

2.5 大模型智能答复

2.5.1 上下文对话管理

系统维护每个用户或群的对话历史,构建上下文进行智能答复:

public void modelGiveAnswer(String user_id, Boolean group, String addId) throws Exception { QueryWrapper<Msg> msgQueryWrapper = new QueryWrapper<>(); String finalQueryId = ""; if (group) { finalQueryId = user_id + addId; } else { finalQueryId = user_id; } msgQueryWrapper.eq("chat_room_or_user_id", finalQueryId); List<Msg> msgList = msgMapper.selectList(msgQueryWrapper); // 调用大模型生成答复 String answer = Step2_AnswerSmart.SmartWork( "7642293093576425524", // botId finalQueryId, // user_id msgList // 历史消息列表 ); answer = answer.replaceAll("\\\\n", "\n"); // 存储答复消息 Msg tempMsg = new Msg(); tempMsg.setChatRoomOrUserId(finalQueryId); tempMsg.setSender("客服人员"); tempMsg.setContent(answer); tempMsg.setType("answer"); tempMsg.setRole("assistant"); tempMsg.setCreateTime(new Date()); msgMapper.insert(tempMsg); }
2.5.2 信息提炼模型

系统还集成了专门的信息提炼大模型,用于从非结构化文本中提取结构化信息:

String uploadInfo = Step8_InfoExtractSmart.SmartWork( UUID.randomUUID().toString(), totalInfo ); Car car = new Car(); car.setInfo(JSON.toJSON(uploadInfo).toString()); car.setCreateTime(new Date()); carMapper.insert(car);

三、数据库设计与优化

3.1 核心表结构设计

3.1.1 好友表 (friend1)
CREATE TABLE friend1 ( id INT PRIMARY KEY AUTO_INCREMENT, user_id VARCHAR(64) NOT NULL COMMENT '企业微信用户ID', nick_name VARCHAR(255) COMMENT '昵称', remark VARCHAR(255) COMMENT '备注名', conversation_id VARCHAR(64) COMMENT '会话ID', create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_user_id (user_id) );
3.1.2 群组表 (group3)
CREATE TABLE group3 ( id INT PRIMARY KEY AUTO_INCREMENT, chat_room_id VARCHAR(64) NOT NULL COMMENT '群聊ID', nick_name VARCHAR(255) COMMENT '群名称', create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_chat_room_id (chat_room_id) );
3.1.3 消息表 (msg)
CREATE TABLE msg ( id BIGINT PRIMARY KEY AUTO_INCREMENT, chat_room_or_user_id VARCHAR(64) NOT NULL COMMENT '会话ID', sender VARCHAR(255) COMMENT '发送者', content TEXT COMMENT '消息内容', type VARCHAR(50) COMMENT '消息类型', role VARCHAR(50) COMMENT '角色(user/assistant)', create_time DATETIME DEFAULT CURRENT_TIMESTAMP );
3.1.4 车辆信息表 (car)
CREATE TABLE car ( id BIGINT PRIMARY KEY AUTO_INCREMENT, info JSON COMMENT '提炼的车源信息', create_time DATETIME DEFAULT CURRENT_TIMESTAMP );

3.2 分页查询优化

@PostMapping("/select_friend1_list") public Res select_friend1_list(@RequestBody Friend1 friend1) { QueryWrapper<Friend1> queryWrapper = new QueryWrapper<>(); if (!MyUtils.blankFlag(friend1.getNickName())) { queryWrapper.like("nick_name", friend1.getNickName()); } Integer total = Math.toIntExact(friend1Mapper.selectCount(queryWrapper)); MyUtils.selectByPageManage(total, friend1); queryWrapper.last("limit " + friend1.getStart() + "," + friend1.getEnd()); List<Friend1> friend1List = friend1Mapper.selectList(queryWrapper); HashMap<Object, Object> hashMap = new HashMap<>(); hashMap.put("total", total); hashMap.put("data", friend1List); return Res.success(hashMap); }

四、关键技术难点与解决方案

4.1 并发安全与数据一致性

问题:多个线程同时操作共享缓存和文件时可能产生竞态条件。

解决方案

  1. 使用ReentrantReadWriteLock实现读写锁分离

  2. 缓存操作与文件操作保持原子性

  3. 消息ID去重机制

private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); // 写操作加写锁 lock.writeLock().lock(); try { // 业务操作 } finally { lock.writeLock().unlock(); } // 读操作加读锁 lock.readLock().lock(); try { // 业务操作 } finally { lock.readLock().unlock(); }

4.2 图片处理性能优化

问题:图片下载、上传涉及网络IO,可能成为系统瓶颈。

解决方案

  1. 使用异步处理或线程池

  2. 优化图片压缩策略

  3. 设置合理的超时时间

// 线程池配置建议 @Bean public ExecutorService imageProcessExecutor() { return new ThreadPoolExecutor( 5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100), new ThreadPoolExecutor.CallerRunsPolicy() ); }

4.3 大模型调用稳定策略

问题:大模型API调用可能失败或超时,影响用户体验。

解决方案

  1. 实现降级策略

  2. 请求重试机制

  3. 本地缓存常用答复

public String callModelWithRetry(String botId, String userId, List<Msg> history) { int maxRetries = 3; int retryCount = 0; while (retryCount < maxRetries) { try { return Step2_AnswerSmart.SmartWork(botId, userId, history); } catch (Exception e) { retryCount++; if (retryCount >= maxRetries) { return "系统繁忙,请稍后再试..."; } Thread.sleep(1000 * retryCount); // 指数退避 } } return "系统繁忙,请稍后再试..."; }

五、系统部署与运维

5.1 部署架构

┌─────────────────────────────────────────────────────────┐ │ 部署架构 │ ├─────────────────────────────────────────────────────────┤ │ │ │ 企业微信服务器 ←→ Python监听服务(ECS) │ │ ↓ │ │ Java SpringBoot应用(ECS) │ │ ↓ │ │ 阿里云OSS(图片存储) │ │ ↓ │ │ 阿里云RDS(MySQL数据库) │ │ │ └─────────────────────────────────────────────────────────┘

5.2 配置文件管理

yaml

复制

下载

# application.yml 关键配置 spring: datasource: url: jdbc:mysql://localhost:3306/wechat_bigdata username: ${DB_USERNAME} password: ${DB_PASSWORD} driver-class-name: com.mysql.cj.jdbc.Driver # 阿里云OSS配置 aliyun: oss: endpoint: ${OSS_ENDPOINT} access-key-id: ${OSS_ACCESS_KEY_ID} access-key-secret: ${OSS_ACCESS_KEY_SECRET} bucket-name: ${OSS_BUCKET_NAME} # 系统常量 constant: self-id: ${SELF_WECHAT_ID} image-save-path: /tmp/wechat_images/

5.3 监控与告警

@Component public class SystemMonitor { private static final Logger logger = LoggerFactory.getLogger(SystemMonitor.class); @Scheduled(fixedRate = 60000) public void monitorCacheSize() { int cacheSize = Constants.WX_INFO_LIST.size(); if (cacheSize > 1000) { logger.warn("消息缓存过大,当前大小: {}", cacheSize); } if (cacheSize > 2000) { logger.error("消息缓存严重过大,请立即处理: {}", cacheSize); // 发送告警通知 sendAlert("消息缓存过大,当前大小: " + cacheSize); } } }

六、总结与展望

6.1 项目亮点

  1. 实时性:毫秒级消息响应,不错过任何商机

  2. 智能化:AI驱动的意图识别与信息提炼

  3. 可扩展:模块化设计,易于接入新的AI能力

  4. 安全性:完善的并发控制与数据备份机制

  5. 可观测:全链路日志跟踪与监控告警

6.2 优化方向

  1. 引入消息队列:使用RabbitMQ/Kafka削峰填谷

  2. 增加缓存层:使用Redis缓存热点数据

  3. 模型优化:训练专属垂直领域模型提升准确率

  4. 多租户支持:支持多个企业微信账号同时接入

  5. 可视化看板:开发数据统计与监控Dashboard

6.3 心得体会

通过本项目的实践,我们深刻体会到:

  1. 架构设计的重要性:良好的分层设计使系统易于维护和扩展

  2. 并发安全的必要性:在企业级应用中,线程安全是不可忽视的基础

  3. AI与传统业务的融合:大模型能力与业务场景结合能产生巨大价值

  4. 异常处理的完善性:完善的异常处理是系统稳定运行的保障

未来,我们将继续深化AI在客户服务领域的应用,打造更智能、更高效的汽车销售辅助系统。