# 微信服务号接入指南(患者端) > **版本**: v1.0 > **创建日期**: 2026-01-04 > **目标**: 为患者端接入微信服务号,实现访视提醒和消息推送 > **预估工作量**: 3天 --- ## 📋 一、准备工作清单 ### 1.1 微信服务号信息 ✅ **已完成**: - 服务号名称:`AI for 临床研究` - AppID:`wx062568ff49e4570c` - AppSecret:`c0d19435d1a1e948939c16d767ec0faf` - 认证状态:✅ 已认证(企业认证) - 主体名称:`北京壹证循科技有限公司` ### 1.2 需要配置的参数 🔧 **待配置**: 1. **Token**(3-32位字符串) 2. **EncodingAESKey**(43位字符串) 3. **服务器URL**(回调地址) --- ## 🔐 二、生成Token和EncodingAESKey ### 2.1 Token生成(推荐使用随机字符串) ```bash # 方法1:使用OpenSSL(推荐) openssl rand -base64 24 | tr -d '/+=' | cut -c1-32 # 方法2:使用Node.js node -e "console.log(require('crypto').randomBytes(24).toString('base64').replace(/[\/\+=]/g, '').substring(0, 32))" # 方法3:在线生成器 # https://suijimimashengcheng.51240.com/ ``` **推荐Token**(示例,请重新生成): ``` IitPatientWechat2026Jan04Abc ``` ### 2.2 EncodingAESKey生成(必须43位) ```bash # 方法1:使用OpenSSL(推荐) openssl rand -base64 43 | tr -d '/+=' | head -c 43 # 方法2:使用Node.js node -e "console.log(require('crypto').randomBytes(32).toString('base64').replace(/[\/\+=]/g, '').substring(0, 43))" # 方法3:微信公众平台随机生成(最简单) # 登录微信公众平台 → 基本配置 → 消息加密密钥 → 点击"随机生成" ``` **推荐EncodingAESKey**(示例,请重新生成): ``` abcdefghijklmnopqrstuvwxyz0123456789ABC ``` --- ## ⚙️ 三、配置步骤(详细) ### 3.1 更新环境变量 编辑 `backend/.env` 文件,添加以下配置: ```env # ========================================== # 微信服务号配置(患者端) # ========================================== # 微信服务号基础配置 WECHAT_MP_APP_ID=wx062568ff49e4570c WECHAT_MP_APP_SECRET=c0d19435d1a1e948939c16d767ec0faf # 微信服务号回调配置(消息加解密,安全模式) WECHAT_MP_TOKEN=IitPatientWechat2026Jan04Abc WECHAT_MP_ENCODING_AES_KEY=abcdefghijklmnopqrstuvwxyz0123456789ABC # 微信小程序配置(可选,后续开发) WECHAT_MINI_APP_ID= ``` ⚠️ **注意**: 1. Token和EncodingAESKey必须与微信公众平台配置的**完全一致** 2. Token长度:3-32位,建议使用英文字母和数字 3. EncodingAESKey长度:**必须43位**,大小写敏感 ### 3.2 配置微信公众平台 #### Step 1: 登录微信公众平台 访问:https://mp.weixin.qq.com/ 使用管理员微信扫码登录(账号:`zhi***ng`) #### Step 2: 进入基本配置页面 ``` 左侧菜单 → 设置与开发 → 基本配置 ``` #### Step 3: 配置服务器地址 找到 **"服务器配置"** 部分,点击 **"修改配置"** 填写以下信息: | 配置项 | 值 | 说明 | |--------|-----|------| | **URL** | `https://iit.xunzhengyixue.com/api/v1/iit/patient-wechat/callback` | 生产环境回调URL | | **Token** | `IitPatientWechat2026Jan04Abc` | 与.env中的WECHAT_MP_TOKEN一致 | | **EncodingAESKey** | `abcdefghijklmnopqrstuvwxyz0123456789ABC` | 与.env中的WECHAT_MP_ENCODING_AES_KEY一致 | | **消息加解密方式** | ✅ **安全模式(推荐)** | 选择"安全模式" | | **数据格式** | ✅ **XML** | 默认选择 | **本地开发环境**(使用natapp内网穿透): ``` URL: https://devlocal.xunzhengyixue.com/api/v1/iit/patient-wechat/callback ``` #### Step 4: 点击"提交"并验证 微信会发送GET请求到您的服务器进行验证: ``` GET https://iit.xunzhengyixue.com/api/v1/iit/patient-wechat/callback?signature=xxx×tamp=xxx&nonce=xxx&echostr=xxx ``` **验证成功标志**: - ✅ 页面显示"配置成功" - ✅ "服务器配置"状态为"已启用" **验证失败原因**: - ❌ Token不一致 - ❌ 服务器无法访问(防火墙、未部署) - ❌ 代码逻辑错误(签名验证失败) #### Step 5: 启用服务器配置 验证成功后,点击 **"启用"** 按钮。 ⚠️ **注意**:启用后,公众号的消息和事件会推送到您的服务器,不会显示在公众平台后台。 --- ## 🧪 四、测试验证 ### 4.1 测试URL验证(手动测试) 在配置微信公众平台时,点击"提交"按钮会自动触发URL验证。 查看后端日志: ```bash # 本地开发 cd D:\MyCursor\AIclinicalresearch\backend npm run dev # 查看日志 # 应该看到类似以下日志: # ✅ 微信服务号回调控制器初始化成功 # 📥 收到微信服务号 URL 验证请求 # ✅ URL 验证成功,返回 echostr ``` ### 4.2 测试脚本1:验证Token和AESKey配置 创建测试脚本 `backend/src/modules/iit-manager/test-patient-wechat-config.ts`: ```typescript import dotenv from 'dotenv'; import crypto from 'crypto'; dotenv.config(); console.log('🔧 微信服务号配置检查\n'); // 1. 检查必需的环境变量 const requiredEnvs = [ 'WECHAT_MP_APP_ID', 'WECHAT_MP_APP_SECRET', 'WECHAT_MP_TOKEN', 'WECHAT_MP_ENCODING_AES_KEY', ]; let hasError = false; requiredEnvs.forEach((key) => { const value = process.env[key]; if (!value) { console.error(`❌ 缺少环境变量: ${key}`); hasError = true; } else { console.log(`✅ ${key}: ${value.substring(0, 10)}... (长度: ${value.length})`); } }); if (hasError) { console.error('\n❌ 配置不完整,请检查 .env 文件'); process.exit(1); } // 2. 验证Token长度 const token = process.env.WECHAT_MP_TOKEN!; if (token.length < 3 || token.length > 32) { console.error(`\n❌ Token长度不正确: ${token.length}位(应为3-32位)`); hasError = true; } else { console.log(`\n✅ Token长度正确: ${token.length}位`); } // 3. 验证EncodingAESKey长度 const aesKey = process.env.WECHAT_MP_ENCODING_AES_KEY!; if (aesKey.length !== 43) { console.error(`❌ EncodingAESKey长度不正确: ${aesKey.length}位(必须43位)`); hasError = true; } else { console.log(`✅ EncodingAESKey长度正确: 43位`); } // 4. 测试签名生成 console.log('\n🔐 测试签名生成...'); const timestamp = Date.now().toString(); const nonce = Math.random().toString(36).substring(2); const arr = [token, timestamp, nonce].sort(); const str = arr.join(''); const signature = crypto.createHash('sha1').update(str).digest('hex'); console.log(`生成的签名: ${signature}`); console.log(`✅ 签名生成功能正常`); // 5. 总结 if (hasError) { console.error('\n❌ 配置检查失败,请修复错误后重试'); process.exit(1); } else { console.log('\n✅ 配置检查通过!可以开始配置微信公众平台'); console.log('\n📋 配置信息(用于微信公众平台):'); console.log(`URL: https://iit.xunzhengyixue.com/api/v1/iit/patient-wechat/callback`); console.log(`Token: ${token}`); console.log(`EncodingAESKey: ${aesKey}`); console.log(`消息加解密方式: 安全模式(推荐)`); } ``` **运行测试**: ```bash cd backend npx tsx src/modules/iit-manager/test-patient-wechat-config.ts ``` ### 4.3 测试脚本2:模拟微信URL验证请求 创建测试脚本 `backend/src/modules/iit-manager/test-patient-wechat-url-verify.ts`: ```typescript import axios from 'axios'; import crypto from 'crypto'; import dotenv from 'dotenv'; dotenv.config(); const BASE_URL = 'http://localhost:3001'; const TOKEN = process.env.WECHAT_MP_TOKEN || ''; async function testUrlVerification() { console.log('🧪 测试微信服务号URL验证\n'); // 1. 准备参数 const timestamp = Date.now().toString(); const nonce = Math.random().toString(36).substring(2, 12); const echostr = 'test_echo_' + Math.random().toString(36).substring(2); // 2. 生成签名 const arr = [TOKEN, timestamp, nonce].sort(); const str = arr.join(''); const signature = crypto.createHash('sha1').update(str).digest('hex'); console.log('📝 请求参数:'); console.log(` timestamp: ${timestamp}`); console.log(` nonce: ${nonce}`); console.log(` echostr: ${echostr}`); console.log(` signature: ${signature}\n`); // 3. 发送GET请求 try { const url = `${BASE_URL}/api/v1/iit/patient-wechat/callback`; const response = await axios.get(url, { params: { signature, timestamp, nonce, echostr, }, }); console.log('✅ URL验证成功!'); console.log(`返回内容: ${response.data}`); if (response.data === echostr) { console.log('✅ 返回的echostr正确'); } else { console.error('❌ 返回的echostr不正确'); } } catch (error: any) { console.error('❌ URL验证失败:', error.message); if (error.response) { console.error('响应状态:', error.response.status); console.error('响应内容:', error.response.data); } } } testUrlVerification(); ``` **运行测试**: ```bash # 先启动后端服务 npm run dev # 新开一个终端,运行测试 npx tsx src/modules/iit-manager/test-patient-wechat-url-verify.ts ``` ### 4.4 测试关注事件 1. 用测试微信号关注公众号:`AI for 临床研究` 2. 查看后端日志,应该看到: ``` 📥 收到微信服务号回调消息 🔐 检测到加密消息,开始解密... ✅ 消息解密成功 📬 提取用户消息成功 🎯 处理事件消息: subscribe 👤 用户关注公众号: oXXXXXXXXXXXXXXXXX ``` ### 4.5 测试文本消息 1. 在公众号对话框发送文本消息:`你好` 2. 查看后端日志,应该看到: ``` 📥 收到微信服务号回调消息 🔐 检测到加密消息,开始解密... ✅ 消息解密成功 💬 处理文本消息: 你好 📝 文本消息已记录 ``` --- ## 🚀 五、部署上线 ### 5.1 本地开发环境(natapp内网穿透) **1. 启动natapp**: ```bash # Windows cd D:\tools\natapp natapp.exe -authtoken=YOUR_TOKEN -subdomain=devlocal ``` **2. 验证映射**: 访问:`https://devlocal.xunzhengyixue.com/api/v1/iit/health` 应该返回: ```json { "status": "ok", "module": "iit-manager", "version": "1.1.0" } ``` **3. 配置微信公众平台**: ``` URL: https://devlocal.xunzhengyixue.com/api/v1/iit/patient-wechat/callback ``` ### 5.2 生产环境(SAE) **1. 更新SAE环境变量**: 登录阿里云SAE控制台 → 应用管理 → 环境变量配置 添加以下环境变量: ``` WECHAT_MP_APP_ID=wx062568ff49e4570c WECHAT_MP_APP_SECRET=c0d19435d1a1e948939c16d767ec0faf WECHAT_MP_TOKEN=IitPatientWechat2026Jan04Abc WECHAT_MP_ENCODING_AES_KEY=abcdefghijklmnopqrstuvwxyz0123456789ABC ``` **2. 部署代码**: ```bash cd backend ./deploy-to-sae.ps1 ``` **3. 验证部署**: 访问:`https://iit.xunzhengyixue.com/api/v1/iit/health` **4. 配置微信公众平台**: ``` URL: https://iit.xunzhengyixue.com/api/v1/iit/patient-wechat/callback ``` **5. 配置IP白名单**(重要): 登录微信公众平台 → 基本配置 → IP白名单 添加SAE应用的出口IP(可以从SAE控制台查看) --- ## 📋 六、常见问题排查 ### Q1: URL验证失败,提示"Token验证失败" **原因**: - Token配置不一致(大小写、多余空格) - 签名计算错误 **解决方法**: 1. 检查 `.env` 文件中的 `WECHAT_MP_TOKEN` 是否与微信公众平台配置一致 2. 运行配置检查脚本:`npx tsx src/modules/iit-manager/test-patient-wechat-config.ts` 3. 查看后端日志,确认签名计算过程 ### Q2: URL验证失败,提示"请求URL超时" **原因**: - 服务器未启动 - 防火墙阻止 - URL配置错误 **解决方法**: 1. 确认后端服务已启动:`npm run dev` 2. 本地开发确认natapp已启动 3. 生产环境确认SAE应用状态正常 4. 使用浏览器直接访问健康检查接口测试连通性 ### Q3: 消息解密失败 **原因**: - EncodingAESKey配置不一致 - EncodingAESKey长度不正确(必须43位) **解决方法**: 1. 检查 `.env` 文件中的 `WECHAT_MP_ENCODING_AES_KEY` 长度是否为43位 2. 确认与微信公众平台配置完全一致(包括大小写) 3. 重新生成EncodingAESKey并同步更新 ### Q4: 收不到用户消息 **原因**: - 服务器配置未启用 - 回调URL配置错误 - 服务端代码异常 **解决方法**: 1. 登录微信公众平台,确认"服务器配置"状态为"已启用" 2. 查看后端日志,确认是否收到POST请求 3. 检查是否有异常日志 --- ## 📝 七、后续开发计划 ### Phase 1: 基础消息推送(当前) - [x] 创建PatientWechatCallbackController - [x] 创建PatientWechatService - [x] 配置路由和环境变量 - [ ] 测试URL验证 - [ ] 测试消息接收 ### Phase 2: 患者绑定功能 - [ ] 创建患者绑定数据表 - [ ] 开发患者绑定H5页面 - [ ] 实现手机号验证码功能 - [ ] 实现患者身份验证逻辑 ### Phase 3: 模板消息推送 - [ ] 申请模板消息权限 - [ ] 设计访视提醒模板 - [ ] 开发定时任务检测到期访视 - [ ] 实现模板消息推送 ### Phase 4: 微信小程序 - [ ] 注册微信小程序 - [ ] 搭建小程序框架 - [ ] 开发核心页面 - [ ] 前后端联调 --- ## 📞 联系方式 如有问题,请联系: - 技术负责人:冯志博 - 邮箱:gofeng117@163.com - 微信:aiforresearch --- **最后更新**:2026-01-04 **文档版本**:v1.0