
简介信呼协同办公OA系统v1.9.1是一套开源的企业办公自动化源码面向需要快速搭建内部协同平台的各类企事业单位也适合PHP开发者和OA二次开发人员学习参考。该版本主要整合日程管理、任务分配、文件共享、即时通讯、审批流程、考勤管理等常用功能模块并支持Android和iOS移动端、PC网页及客户端多端接入能够满足移动办公和业务流程数字化需求。压缩包内共1256个文件包括606个php后端逻辑、148个html页面、146个js脚本、231个gif图标、79个png图片及27个css样式等整体大小仅2.83MB目录结构清晰便于部署和定制。已有481人学习下载开发者可借助完整源代码理解OA系统的模块划分、权限控制与接口设计结合自身业务需求进行二次开发构建高效、安全、可扩展的协同办公平台。1. 信呼不是拿来就能用的 OA它更像一套半成品框架值不值得下看你会不会改很多开发者在第一次看到信呼协同办公 OA 系统时会有一个错觉这是个开箱即用的成品。装上、登录、点几个按钮就能把审批跑起来。实际拆过之后我的结论是它确实是一套能省下大量重复劳动的 OA 系统但真正值钱的部分在于它的自定义表单、流程引擎和移动端适配而不在于那几个默认页面。适合的接手人是有一定 PHP 基础、能看懂前后端数据流的开发者或者想要低成本搭一套内部管理系统的中小团队。如果你只想装个 Demo 看看界面这资源不值得下如果你想在三天内搭出一套带审批、考勤、客户管理的系统它会帮你省下至少两周的造轮子时间。2. 部署信呼环境选型、安装步骤与三个入口配置2.1 环境清单与选型理由PHP 版本卡得比想象严但不是不能用信呼 v1.9.1 的服务端语言是 PHP前后端不分离前端主要用到 Bootstrap 框架数据层走 MySQL。这套组合在 OA 场景里算得上务实部署成本低虚拟主机都能跑对中小团队来说不需要一开始就上 Docker 或 K8s。环境选型上要注意一个细节PHP 版本不能太新。项目本身兼容 PHP 5.6 到 7.4 这一段但我在某台测试机上用 PHP 8.0 跑安装向导时遇到过页面报错查日志发现是部分老函数被移除了。如果你非要上 PHP 8.x得先把代码里each()、create_function()这类被废弃的写法做一次全局替换工作量大但不算难。我的建议是直接选 PHP 7.4性能够用兼容性问题最少。# 以 CentOS 7 为例安装 PHP 7.4 及必要扩展 yum install -y epel-release yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm yum install -y yum-utils yum-config-manager --enable remi-php74 yum install -y php php-mysqlnd php-gd php-mbstring php-xml php-curl php-zip这一段命令的作用是先把 PHP 7.4 的软件源打开再一次性装上运行信呼必需的扩展。php-mysqlnd负责 MySQL 连接php-gd用于生成验证码图片php-mbstring处理中文编码没有这几个扩展安装向导会在环境检测页直接标红。装完可以用php -v确认版本再确认扩展是否加载成功。数据库方面MySQL 5.7 或 MariaDB 10.3 都行字符集务必选utf8mb4不只是为了中文不乱码还因为 OA 系统里有人会往备注字段里存 Emoji 表情utf8存不下会变成问号。这个坑我在项目上遇到过两次一次是审批意见一次是客户备注后面统一改成utf8mb4才消停。2.2 部署与初始化目录权限、伪静态和数据库导入一次过信呼的部署方式比较传统把源码扔到 Web 根目录访问/install/走安装向导。整个流程里最容易被忽视的是目录权限。web目录下的upload、cache、runtime这三级目录要求 PHP-FPM 运行用户可写否则安装向导能走完但传不了附件、生成不了缓存表现就是页面卡死或白屏。# 假设代码位于 /data/wwwroot/xinhub 目录运行用户为 www chown -R www:www /data/wwwroot/xinhub chmod -R 755 /data/wwwroot/xinhub chmod -R 777 /data/wwwroot/xinhub/web/upload chmod -R 777 /data/wwwroot/xinhub/web/cache chmod -R 777 /data/wwwroot/xinhub/web/runtime权限设置完后在浏览器里访问安装地址填数据库信息时注意如果数据库和 Web 在同一台机器主机名最好是127.0.0.1而不是localhost原因是一些版本 PHP 的 MySQL 驱动对localhost会尝试走 socket 连接而 socket 文件路径不一定匹配导致连接被拒。这个玄学问题在安装向导页经常让人来回折腾。安装向导最后一步会写入配置文件并导入初始数据。如果这步卡住不动大概率是 SQL 文件太大导致 PHP 执行超时。我一般会在php.ini里把max_execution_time调到 300 秒必要时手动用命令行导入初始 SQLmysql -u root -p xinhub_db install/xinhub.sql这么做的好处是绕过了 PHP 的max_execution_time和post_max_size限制导入失败时能看到 MySQL 的报错原话也方便判断是字段冲突还是编码问题。2.3 登录入口与基础安全配置密码策略、验证码与备份部署完第一件事不是急着建流程而是把系统参数里三个安全项改掉。信呼后台的“系统设置”里有一项登录安全配置默认的登录验证码只在上屏出现密码策略也只是基本的长度校验。按某公司内部规范我会这样改登录失败次数限制设为 5 次超过后锁定 15 分钟强制首次登录修改密码防止初始密码被滥用管理后台路径从默认的/admin.php改成自定义别名减少被扫描器盯上的概率改路径这个操作在信呼里不是改个文件名那么简单。入口文件本身叫admin.php你把它改名成manage.php后需要同步修改应用配置文件里的路由别名否则登录后跳转地址会抛 404。这是我踩过的坑之一后面在避坑章节细说。备份策略上我习惯写一个简单的 shell 脚本每天凌晨用mysqldump导出业务库同时把web/upload目录做增量同步因为 OA 里重要的不只是数据库还有审批附件和头像图片。只备份数据库不备份附件的做法在恢复现场时等于没备份。#!/bin/bash BACKUP_DIR/data/backup/oa DATE$(date %F) mysqldump -uroot -p密码 --single-transaction xinhub_db $BACKUP_DIR/db_$DATE.sql rsync -av /data/wwwroot/xinhub/web/upload /data/backup/oa/upload/ find $BACKUP_DIR -mtime 30 -name *.sql -exec rm {} \;这个脚本的逻辑很直白先导数据库再同步附件最后清理 30 天前的过期备份。--single-transaction参数用于 InnoDB 表导出时保持一致快照避免备份过程中有人写入数据导致表结构不一致。恢复时先建库再导入 SQL最后把 upload 目录放回原位。3. 表单设计与自定义流程把审批逻辑落地的核心操作3.1 可视化表单设计器字段类型、布局与数据字典信呼最值得花时间研究的是表单设计器。它在“应用中心”里对应自定义表单模块支持文本、数字、日期、下拉框、上传文件等字段类型也能把字段拖到两列或三列布局里。对不写前端的人来说这个设计器基本能把 80% 的表单需求直接落地剩下的 20% 要靠改模板。设计表单时要先想清楚数据字典不能见到一个业务需求就加一个字段。我见过一个案例某团队把“请假事由”做成了纯文本字段结果月底统计请假类型时没法按“事假”“病假”“年假”分组因为文本字段无法枚举统计。正确的做法是在表单设计阶段就明确哪些字段参与统计、哪些字段参与流程条件判断这两类字段必须用下拉框或单选控件而不是自由文本。这不是信呼的限制而是所有 OA 表单设计的通用原则。// 自定义表单提交后PHP 端接收参数并写入表的逻辑示意 $type $_POST[leave_type]; // 下拉框请假类型 $hours floatval($_POST[leave_hours]); // 数字框请假时长 if (!in_array($type, [事假, 病假, 年假])) { exit(请假类型不合法); } // 数据校验通过后再调用模型层写入这段代码关注两个细节后端不仅要接收参数还必须做合法校验不能相信前端传什么就存什么数字字段要用floatval转换类型否则 SQL 拼接时可能产生注入语义。表单设计器生成的代码会在模型层做一层封装但业务里复杂的表单往往需要自己写检测逻辑这就是为什么要懂表单背后映射的数据结构。3.2 流程引擎配置节点、条件分支与会签信呼的流程引擎支持顺序审批、条件分支、会签三种基本模式配置界面在后台的“审批流程”模块。顺序审批最直观发起人提交后按设定好的审批人顺序流转任意节点驳回则回到发起人。条件分支则依赖表单里的字段值来决定下一节点人比如“请假天数大于 3 天走部门主管加 HR 复核小于等于 3 天只走部门主管”。配置条件分支时要特别注意一个边界问题条件判断的优先级。系统默认从上到下匹配第一个满足的条件生效后面的分支不再判断。所以设计条件时要把“大于等于 10 天”放在“大于 3 天”前面否则大额请假会被误判到普通审批节点。这个问题的本质是区间判断的包含关系写条件顺序时先写特殊再写通用就永远不会翻车。会签模式用得少但一旦用起来就要理解它的通过策略。信呼支持“一票否决”和“按比例通过”两种会签结果我在实际项目里通常建议选一票否决理由很简单OA 里会签场景大多出现在费用报销或合同审批这类场景的安全取向是保守的。按比例通过可能会导致少数人的反对意见被忽略事后追责时难说清。// 流程节点处理逻辑判断当前节点是否需要条件分支 $next $db-query(SELECT * FROM flow_branch WHERE node_id $current_node AND field days); foreach ($next as $branch) { if ($days intval($branch[min_value]) $days intval($branch[max_value])) { $target_node $branch[target_node]; break; } }这里的关键参数是min_value和max_value它们定义了每个分支的数值范围。注意区间写法是和这样做是为了避免边界值同时匹配两个分支的场景。如果设计表单时把天数用文本字段存了这段逻辑就废了因为文本比较和数值比较在 SQL 里的结果是完全不同的这也是为什么我在上一节强调参与流程判断的字段必须用数字类型。3.3 字段加密设置加的是密但也给后续查询挖了坑这是信呼里最容易被低估的功能也是最近不少人搜“oa系统搭建流程的字段设置了加密设置”时真正想解决的问题。信呼的自定义表单可以对指定字段开启加密存储数据落库前经过可逆算法处理界面上显示正常原文但直接查数据库看到的是密文。加密设置的入口在表单字段属性里勾选“加密显示”后保存即生效。这个功能对保护敏感信息有价值比如员工身份证号、银行卡、薪资数字这类字段。但开启时要想清楚三个问题第一加密字段不能作为流程条件分支的判断依据因为判断时拿的是密文和条件值比对永不相等第二加密字段不能做模糊搜索你在列表页搜“张三”能搜到搜“张”就搜不到了第三加密字段导出 Excel 时需要用系统提供的数据解密接口处理直接查表导出的是密文。// 字段加密写入的逻辑示意 $key 自定义密钥字符串; $encrypted openssl_encrypt($value, AES-128-CBC, $key, 0, $iv); // 查询条件里碰到加密字段时的处理方式 // 不能用 LIKE只能先解密后比对或者按关联 ID 查询 $sql SELECT * FROM employee WHERE id_number_enc . encrypt($input) . ;参数说明AES-128-CBC是最常用的对称加密算法需要保证$key和$iv在加解密两端的值一致。信呼把这套逻辑封装在底层模型里正常业务代码调用时感觉不到加密的存在。但如果你自己写 SQL 绕过模型层就会看到一列乱码。所以我给团队的规矩是涉及加密字段的操作一律走系统封装的模型方法不允许写原生 SQL 直接读表。4. 常用模块改造与系统参数考勤、客户管理、消息通知4.1 考勤模块参数排班方式、外勤打卡与数据修正考勤模块在信呼里做得不算复杂适合固定班制、打卡范围固定的团队。它支持 GPS 定位打卡和 WiFi 打卡两种方式后一种更像“办公区打卡”而不是严格的位置校验适合点位固定的公司。排班参数在后台“考勤设置”里维护支持固定班次和轮班制。实际使用中要注意一个边界外勤打卡。默认设置下超出定位范围根本打不了卡这对销售岗和经常外出的人不友好。我在部署时一般这样调把定位范围设成对应的半径值比如 500 米同时开启“外勤打卡”开关允许员工在范围外填写外勤说明提交后由直属主管审批。这样既保了管理底线又不至于让打卡机制变成业务执行的阻力。数据修正也是一个常规操作。员工因为手机没电、忘打卡等原因漏卡后通常需要管理员在后台勾选补卡记录。信呼把这类操作记录在系统日志里这个设计很好审计时能追溯是谁修正了考勤数据。-- 查看某员工某月考勤汇总的常用查询 SELECT user_name, SUM(work_hours) AS total_hours, SUM(late_count) AS late_times, SUM(leave_hours) AS leave_hours FROM attend_detail WHERE user_id 123 AND month 2025-06 GROUP BY user_name;这段 SQL 是从考勤明细表做月度聚合late_count和leave_hours字段是系统定时任务每天计算好的结果。注意查询时用了month字段而不用DATE_FORMAT(create_time, %Y-%m)原因是前者能走索引数据量大时性能差异会很明显。4.2 客户管理模块字段扩展与权限隔离信呼的客户管理模块本质是一张可扩展的客户信息表加上跟进记录。基础字段有客户名称、联系人、电话、地址但不同团队需要的字段完全不同比如做外贸的想加“贸易术语”做工程的想加“项目阶段”。所以这个模块的正确打开方式还是表单设计器那套逻辑在客户字段配置里追加自定义字段。权限隔离是客户模块的核心诉求。信呼支持按部门、按角色、按员工三种数据权限模式在“数据权限”配置里选择哪种仅本人可见、哪些是部门共享。我给某团队配置时是这样设计的销售只能看到自己的客户销售主管看整个部门的客户公司的财务和行政默认看不到客户数据。这套配置非常适合中小团队既能防止撞单又不影响管理效率。跟进记录模块要注意一个数据流问题每次跟进写的备注在系统里是一个独立子表查询客户列表时默认不加载只有点击进详情页才读取。这是性能设计上的取舍好处是列表页查询不会被大文本字段拖慢坏处是列表页做导出时不会自动包含跟进内容。如果你需要做带跟进内容的导出报表得自己写一个关联查询把子表内容拼到主表结果里。4.3 消息通知配置邮件、企业微信机器人与短信OA 系统的关键动作必须有消息通知否则流程在某个节点卡两天没人知道。信呼内置了邮件通知、企业微信/钉钉群机器人、短信三种渠道。邮件和企业微信基本免费短信要购买第三方服务。企业微信群机器人的配置成本最低在企业微信群里添加自定义机器人拿到 Webhook 地址然后填到信呼的“消息配置”里。系统会把待办事件、流程到达消息推成群里的一条卡片消息。我在实际项目中会用这个方式做“审批超时提醒”每天下午四点半机器人自动发一条消息把超过 24 小时未处理的审批单列出来效果很好。// 企业微信机器人推送的简化实现 $webhook https://qyapi.weixin.qq.com/cgi-bin/webhook/send?keyxxx; $data [ msgtype text, text [ content 待办提醒你有 3 条审批未处理请及时处理。 ] ]; $result curl_post_json($webhook, json_encode($data));这里的curl_post_json是一个按标准 POST 方式提交 JSON 的封装函数重点是Content-Type必须设置为application/json否则机器人会拒收消息。超时提醒任务的实现方式是在定时任务里查所有status pending的记录统计超时时间再批量推送到群里。5. 避坑信呼 OA 搭建过程中我踩过的五个具体问题5.1 现象表单提交后流程状态一直停留在“未提交”原因流程启动节点配置里没有正确绑定“发起人”。信呼的流程设计是先建流程再绑定到具体表单绑定这一步经常被跳过或者绑错了一个测试表单。另一个常见原因是发起人权限设置为“指定角色”而当前提交人不在该角色组里系统会静默拒绝发起不给任何提示。解决后台进入流程设计检查“适用表单”和“发起人范围”两个选项。前者要确保绑定的是当前使用的表单 ID后者要么选“任何人”要么确认发起人所属角色已经被勾选。改完重新测试一张新单据不要用旧数据测旧数据的流程实例可能已经缓存了错误配置。5.2 现象给字段启用了加密后列表页搜索该字段搜不到数据原因加密字段落库为密文列表页默认搜索逻辑把输入关键词先做匹配再查库匹配的是密文自然查不到。这个坑在表单设计器开启加密的那一刻就已经埋下只是很多人上线后第一次用搜索功能才发现。解决不能靠改配置解决除非放弃加密。我的方案是额外建一个不可见的辅助字段存明文摘要只用于搜索比如对手机号取后四位再加一个唯一 ID 做成索引列。这样既保留密文存储的安全语义又让搜索功能可用。注意辅助字段不能存完整明文否则加密的意义就没了。5.3 现象配置好伪静态后访问二级页面全部 404原因信呼根目录同时存在 PHP 入口文件和静态资源目录很多人在 Nginx 里直接把try_files写成了只匹配 PHP没有给静态资源目录放行。实际是静态文件请求也被路由到了 PHP 解析器导致图片、CSS 全部抓不到。解决Nginx 配置里要区分静态资源和动态请求。location /upload/和location /static/直接走静态文件返回其余请求再进入 rewrite 规则。改完配置记得先nginx -t检查语法再reload不要直接重启避免正在跑的在线用户被中断。location / { if (!-e $request_filename) { rewrite ^/(.*)$ /index.php?s$1 last; } } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }5.4 现象定时任务每天不执行或者执行了两次原因信呼的定时任务依赖系统 crontab 调用如果服务器上 cron 服务本身没启用任务自然跑不起来。执行两次的场景通常是安装了两份调度配置比如系统自带的 crontab 和宝塔面板的定时任务同时配置了同一条命令。解决查看调度命令实际路径用crontab -l检查是否重复注册。信呼的官方文档里写明了推荐的 cron 配置只需要把php think的调用路径换成服务器上实际 PHP 二进制路径即可。排除问题时先手动执行一次命令确认输出没有报错再交给 crontab。5.5 现象升级到新版本后自定义表单无法显示原因信呼升级时更新了数据库结构或表单字段存储表而自定义表单里新增的字段类型和旧版本不兼容或者升级脚本覆盖了自定义代码。更隐蔽的情况是缓存目录里残留了旧版本的编译模板文件。解决升级前把web/cache目录整体备份升级后清空再重建。如果自定义表单字段丢失不要手工改数据库直接从备份的 SQL 里恢复对应表的记录然后跑一遍系统自带的字段缓存重建。从那以后我每次升级都强制先看变更日志里有没有 form 相关改动再决定备份策略。6. 进阶验证用命令行脚本做一次全链路自动化测试部署完信呼并配好流程后不能只靠人肉点页面验证。我习惯写一套命令行脚本模拟员工操作登录获取会话、提交一张请假单、模拟审批人通过、检查流程是否流转到下一节点。这套脚本不仅能验证功能链路还能在每次升级或改配置后快速回归比人工测试省太多时间。先写登录脚本。信呼的登录接口返回加密后的会话数据需要用系统封装的验证逻辑生成请求头。模拟登录时注意密码加密方式不是明文 MD5而是加盐后的一次 MD5所以脚本里必须复用系统的加密函数不能自己另写一套。#!/bin/bash # 模拟完整请假流程的可用性检查 BASEhttps://oa.example.com COOKIE$(curl -s -c /tmp/oa_cookie.txt -d usernametest01password加密后密码 $BASE/index.php?alogin | grep -o token[^]*) # 提交请假单 curl -s -b /tmp/oa_cookie.txt \ -d type事假hours4reason自动化测试提交flow_id12 \ $BASE/index.php?asave_form /tmp/leave_result.txt # 查询流程状态 curl -s -b /tmp/oa_cookie.txt $BASE/index.php?acheck_flowbill_id$(grep -o bill_id[0-9]* /tmp/leave_result.txt)这段脚本做了两件事先发 POST 提交表单再根据返回的bill_id查询流程状态。-b参数带上会话 cookie 是为了让服务端认识请求者身份grep提取返回参数是为了动态拿到新生成的单据号。如果第三行输出显示当前节点是“部门主管审批中”说明流程已经跑起来了。接着验证审批动作。审批接口要求携带两个关键参数bill_id和agree_status前者标识哪张单子后者是审批结论。审批通过后再查一次流程状态确认节点跳转。这一步能抓出两种典型问题审批人角色配置错误、流程节点跳转条件没生效。跑脚本时我会用set -x打开执行过程输出方便看清每次请求的返回码。HTTP 200 不代表业务成功要看返回 JSON 里的code字段是 0 还是负数这是信呼的约定负数代表业务异常。验证通过后这轮脚本可以留下纳入每周一次的巡检任务确保系统没有因为配置变更而悄悄坏掉。信呼这套系统给我最大的教训是OA 平台的硬伤从来不在功能缺不缺而在配置链路太长任何一个环节设定错误问题都要到真正跑业务那天才暴露。从那以后我每次上线新流程都会强制走一遍自动化脚本核对链路不依赖肉眼点页面。希望这份拆解能帮你把信呼用得顺一些少走我当初那些弯路。本文还有配套的精品资源点击获取