1. 项目背景与核心价值
企业微信作为国内主流的企业级IM工具,其审批功能在日常办公中扮演着重要角色。而ERP系统作为企业资源管理的核心平台,两者间的数据互通直接影响着业务流程效率。以易飞ERP为例,其最新发布的V9.0版本在API层面对审批流程的支持有了显著增强,这为与企业微信的深度集成提供了技术基础。
在实际业务场景中,我们经常遇到这样的痛点:销售人员在ERP提交的采购申请需要经过多层审批,但审批人往往因未及时登录ERP系统导致流程卡顿。通过将审批流同步至企业微信,审批人可直接在移动端处理待办事项,实测审批时效平均提升60%以上。这种集成方案特别适合制造业、零售业等需要快速响应的行业。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 系统对接原理
整个对接过程基于企业微信自建应用模式实现,主要涉及三个技术组件:
- 易飞ERP的审批模块API(V9.0新增的审核员API)
- 企业微信的自建应用接口
- 中间件服务(推荐使用Python Flask或Java Spring Boot)
数据流向设计为双向同步:
- ERP → 企微:审批单创建/状态变更时触发webhook
- 企微 → ERP:审批结果通过回调接口返回
2.2 关键接口说明
易飞ERP侧需要调用的核心接口:
python复制# 获取待同步审批单
GET /api/v9/approval/pending?dept_id={部门ID}
# 提交审批到企微
POST /api/v9/approval/sync
{
"form_data": {
"applyer": "申请人ID",
"approvers": ["审批人1","审批人2"],
"title": "采购申请-202406001",
"items": [
{"name": "物料编码", "value": "MAT2024"},
{"name": "数量", "value": 100}
]
}
}
企业微信侧需要配置的回调接口:
python复制# 审批结果回调示例
@app.route('/wecom/callback', methods=['POST'])
def handle_callback():
data = request.json
if data['Event'] == 'sys_approval_change':
update_erp_status(
data['ApprovalId'],
data['ApprovalStatus'] # 1-通过 2-驳回
)
3. 实施步骤详解
3.1 环境准备
硬件要求:
- 独立服务器(推荐4核8G配置)
- 固定公网IP(用于企微回调地址)
- SSL证书(必须HTTPS协议)
软件依赖:
bash复制# Python环境示例
pip install requests cryptography flask-sqlalchemy
3.2 企业微信应用配置
- 登录企微管理后台 → 应用管理 → 自建应用
- 创建"ERP审批同步"应用
- 权限配置:
- 必须勾选:审批流程、通讯录读取
- 敏感权限需管理员二次确认
- 设置API接收:
- URL: https://yourdomain.com/wecom/callback
- Token: 自定义32位字符串
- EncodingAESKey: 自动生成
特别注意:IP白名单需提前配置,否则回调请求会被拦截
3.3 ERP系统配置
- 启用审核员API功能:
- 进入系统管理 → 接口设置
- 生成API密钥(建议定期轮换)
- 配置审批模板映射:
sql复制/* 示例数据库配置 */ UPDATE approval_template SET wecom_form_id = 'FORM0001' WHERE erp_form_code = 'PUR001'; - 设置webhook地址:
- 指向中间件服务的/erp/callback端点
4. 核心业务逻辑实现
4.1 审批单同步服务
python复制def sync_approval_to_wecom(erp_approval_id):
# 获取ERP审批单详情
erp_data = get_erp_approval(erp_approval_id)
# 转换字段格式
wecom_form = {
"creator_userid": erp_data['applyer_code'],
"template_id": get_mapped_template(erp_data['form_type']),
"apply_data": {
"contents": [
{
"control": "Text",
"id": "item_name",
"value": {"text": erp_data['item_name']}
}
# 其他字段转换...
]
}
}
# 调用企微API
resp = requests.post(
"https://qyapi.weixin.qq.com/cgi-bin/oa/applyevent",
json=wecom_form,
params={"access_token": get_access_token()}
)
# 处理响应
if resp.json()['errcode'] == 0:
update_sync_status(erp_approval_id, resp.json()['sp_no'])
4.2 状态回调处理
python复制@app.route('/wecom/callback', methods=['POST'])
def handle_callback():
# 验证消息签名
signature = request.args.get('msg_signature')
timestamp = request.args.get('timestamp')
nonce = request.args.get('nonce')
if not verify_signature(signature, timestamp, nonce):
abort(403)
# 解密消息
encrypt_msg = request.json['Encrypt']
decrypted = decrypt_message(encrypt_msg)
# 处理审批状态变更
if decrypted['Event'] == 'sys_approval_change':
update_erp_approval(
decrypted['ThirdNo'],
decrypted['Status'],
decrypted['Approver']
)
# 返回成功响应
return jsonify({
"encrypt": encrypt_response("success"),
"nonce": nonce,
"timestamp": timestamp
})
5. 常见问题解决方案
5.1 企业微信回调失败
典型现象:
- 企微后台显示"回调地址请求超时"
- 日志出现403状态码
排查步骤:
- 检查nginx配置是否正确转发请求
nginx复制location /wecom/callback { proxy_pass http://localhost:5000; proxy_set_header Host $host; } - 验证签名算法实现是否与企微文档一致
- 使用在线工具测试公网可达性
5.2 ERP数据不同步
可能原因及处理:
- 字段映射错误
- 检查数据库中的template_mapping表
- 确认企微模板控件ID与ERP字段对应关系
- 权限不足
- 重新获取API访问令牌
- 检查企微应用的可见范围设置
- 网络隔离
- 测试ERP服务器到中间件的连通性
- 检查防火墙规则
5.3 高并发场景优化
当审批量较大时(如月末集中报销),建议:
- 增加消息队列缓冲
python复制# RabbitMQ示例 channel.basic_publish( exchange='', routing_key='approval_queue', body=json.dumps(approval_data) ) - 实现批处理模式
- 改为每5分钟同步一批次
- 使用GROUP BY减少API调用次数
- 添加重试机制
python复制@retry(stop_max_attempt_number=3, wait_fixed=2000) def call_wecom_api(data): requests.post(wecom_url, json=data)
6. 安全防护措施
- 通信加密
- 强制使用TLS1.2+
- 敏感字段采用AES二次加密
- 权限控制
- 实施RBAC模型
- 审批人与数据可见性绑定
- 审计日志
sql复制CREATE TABLE api_audit_log ( id BIGINT PRIMARY KEY, user_id VARCHAR(32), action VARCHAR(50), params TEXT, ip_address VARCHAR(45), created_at TIMESTAMP ); - 限流防护
- Nginx层限制100请求/秒
- 令牌桶算法控制ERP接口调用
7. 扩展应用场景
7.1 与钉钉/飞书的多平台适配
通过抽象审批适配层,可支持多平台切换:
python复制class ApprovalAdapter(ABC):
@abstractmethod
def submit_approval(self, data): pass
class WeComAdapter(ApprovalAdapter):
def submit_approval(self, data):
# 企业微信实现...
class DingTalkAdapter(ApprovalAdapter):
def submit_approval(self, data):
# 钉钉实现...
7.2 移动端快捷审批
集成企业微信JS-SDK实现:
javascript复制wx.ready(function(){
wx.invoke('getApprovalDetail', {
sp_no: '审批单号'
}, function(res){
if(res.err_msg == 'getApprovalDetail:ok'){
renderApprovalForm(res.data);
}
});
});
7.3 数据分析扩展
将审批数据同步至数据仓库:
sql复制-- 审批时效分析
SELECT
form_type,
AVG(TIMESTAMPDIFF(MINUTE, create_time, approve_time)) as avg_duration
FROM approval_records
GROUP BY form_type;
