
简介这是一份面向企业信息化建设者与PHP开发者的OA系统一体化源代码包整合了OA审批、公文管理、人事管理、客户关系管理、财务管理、工程与项目管理、知识管理等多业务模块支持流程与表单自定义配置并且兼容PC端和移动端可接入钉钉与企业微信便于快速搭建或二次开发办公平台。包内含1403个文件总大小约2.53MB以702个PHP业务逻辑文件、177个HTML页面模板、169个JavaScript交互脚本以及231个GIF图标等为主也包含CSS样式、SQL数据库脚本与字体文件结构分类清晰便于按模块定位与部署。已有221人学习下载。源码包附带了完整的数据库脚本与配置说明可直接部署并利用初始管理员账号体验功能对需要扩展企业OA能力或研究多模块集成方案的开发者这套代码提供了实用的开发参考和基础框架。1. 企业一体化办公平台 OA 源码一套能跑十年的老牌方案手里拿到这套「企业一体化办公平台 OA 系统源代码」的时候第一反应是这玩意儿居然还活着。PHP 5.2 MySQL 的组合放在今天看像是上个时代的古董但恰恰是这种古董级技术栈造就了它极高的兼容性和极低的部署门槛。这套源码不单单是一个 OA——流程配置、表单配置是它的底座上面还挂了公文管理、人事管理EHR、会员管理、行政管理、客户关系管理CRM、财务管理、工程管理、项目管理、知识管理等一整套模块说它是半个 ERP 也不过分。它支持 PC 和手机双端访问还能接入钉钉和企业微信这意味着拿到手就能直接往企业内部推。适合谁两类人一是企业内部的 IT 运维或信息化负责人想低成本快速搭一套能用的办公平台二是想研究老牌 PHP 工作流引擎、表单引擎实现的开发者。接下来我按实际拆解顺序把它从安装到二次开发讲透。2. 拆解系统骨架前端资源背后的技术栈与模块布局2.1 从 CSS 文件嗅探前端技术选型解压源码包后先不急着看 PHP 文件打开 css 目录扫一眼信息量比想象中大。bootstrap_cerulean.css 是 Bootswatch 的 Cerulean 主题Bootstrap 2.x 时代非常流行的一个蓝色系皮肤font-awesome.min.css 是图标库font-awesome-ie7.min.css 这个文件专供 IE7 兼容weui.min.css 是微信团队的 Web UI 样式库它的出现说明移动端页面刻意做得接近微信交互风格。再加上 default.css、webmain.css、webimcss.css、cssm.css 这些手写样式基本可以还原出当时的设计思路PC 端用 Bootstrap 搭框架移动端套 WeUI 风格图标统一走 FontAwesome。这个选型放在当年非常务实。Bootstrap 2.x 对 IE8 的兼容性尚可Cerulean 主题又是免费且观感专业的后台皮肤WeUI 的引入让手机端不需要单独写一套 UI直接复用微信生态的视觉语言。如果要做二次开发建议保留这套前端体系不要去升级 Bootstrap 版本——升级带来的 DOM 结构变化会让所有后台页面重写一遍得不偿失。2.2 功能模块地图不止 OA还是半个 ERP从摘要描述可以确认这套系统包含十个以上业务模块。我按实际使用频率和业务关联度整理如下模块核心功能典型使用场景流程配置流程模板设计、审批节点编排请假、报销、用章申请表单配置自定义字段、表单布局业务数据采集、入离职登记公文管理发文、收文、归档行政公文流转人事管理EHR员工档案、考勤、工资HR 日常管理客户关系管理CRM客户档案、跟进记录销售过程管理项目管理任务分解、进度跟踪项目制协作财务管理费用报销、应收应付财务数据归集行政管理资产、宿舍、车辆行政后勤知识管理文档库、分享、检索内部知识沉淀会员管理会员档案、等级面向 C 端的组织这些模块不是简单的菜单罗列它们共享同一套用户体系和权限模型。也就是说员工在 CRM 里维护的客户信息可以在项目模块中被关联引用公文审批的流程模板也可以复用到人事模块的离职申请中。这个「流程引擎 业务模块」的设计是这套源码最值钱的部分。2.3 入口与权限模型admin 登录后能看到什么初始账号 admin / 123456登录后进入的是系统管理后台。用惯了现代框架的人第一次进去可能会觉得土——没有仪表盘大屏没有酷炫的图表但权限划分是清晰的老式三层次系统管理员admin、部门管理员、普通员工。菜单的可见性按角色配置每个角色的可操作按钮增删改查、导出、审批可以精确到具体模块。如果你打算把它作为企业内部系统正式用起来上线第一步一定是修改 admin 密码然后按部门建立角色、分配权限。源码里权限配置的数据结构是角色 → 菜单 → 操作按钮三层映射在数据表中表现为用户表、角色表、权限表、菜单表四张核心表的关联。二次开发时想要给某个角色增加一个「导出工资单」的按钮就是往菜单表插一条记录并绑定到对应角色不需要动 PHP 逻辑。3. 部署落地环境选型、数据库导入与配置改写全流程3.1 环境选型为什么 PHP 5.2 反而是优势这套系统要求 PHP 5.2 MySQL这在今天的新机器上是个麻烦事——PHP 官方在 5.3 起废弃了mysql_*系列函数到 PHP 7 直接移除。但反过来说它能跑在 PHP 5.2 上意味着任何一台装了老版 phpStudy 或 XAMPP 的 Windows 机器都能直接跑起来不需要处理 Composer 依赖、不需要 Node 环境解压即用。这正是老项目的优势依赖极简逻辑自洽。Windows 下我用的是 phpStudy 2016 老版本集成 PHP 5.2.17 MySQL 5.1Linux 下建议用宝塔面板装 PHP 5.2 或手动编译。MySQL 版本控制在 5.1 ~ 5.5 之间不要用 5.7 以上因为老代码的 SQL 写法可能与新版 MySQL 的默认 SQL_MODE如 ONLY_FULL_GROUP_BY冲突。3.2 数据库初始化导入 webmain/install/db.sql数据库文件在webmain/install/db.sql这是一个完整的数据字典加初始数据的 SQL dump。导入方式有两种# 方式一直接用 mysql 命令导入先建库再导入 mysql -uroot -p -e CREATE DATABASE oa_db DEFAULT CHARACTER SET utf8; mysql -uroot -p --default-character-setutf8 oa_db webmain/install/db.sql # 方式二进入 mysql 交互终端后操作 mysql -uroot -p CREATE DATABASE oa_db DEFAULT CHARACTER SET utf8; USE oa_db; SOURCE webmain/install/db.sql;这里有一个关键参数--default-character-setutf8。如果省略Windows 命令行默认的 GBK 编码会把中文数据导成乱码导致登录后整个界面出现「锟斤拷」字符集灾难。导入完成后可以快速验证一下USE oa_db; SHOW TABLES; -- 正常情况应看到几十张表名称类似 sys_user、flow_template 等 SELECT COUNT(*) FROM sys_user; -- 初始管理员 1~2 条记录看到表结构基本能确认数据库导入没问题。这里补充一句db.sql 里除了用户表还会写入流程模板的初始分类、表单字段的初始字典等这些基础数据决定后续流程配置时下拉框里有哪些选项轻易不要手动去改。3.3 配置文件改写webmainConfig.php1 与 randkey源码包里默认没有webmainConfig.php只有一个webmainConfig.php1这是安装程序的保险机制——只有等你把参数填好了才允许改名激活。进入webmain目录执行改名mv webmain/webmainConfig.php1 webmain/webmainConfig.php然后编辑这个文件核心配置项如下?php // webmain/webmainConfig.php 关键配置 $db_host 127.0.0.1; // 数据库地址本机用 127.0.0.1远程填 IP $db_user root; // 数据库账号 $db_pwd your_password; // 数据库密码改成你自己的 $db_name oa_db; // 数据库名与导入时建的库一致 $randkey almvhcusrywkxvnzgdjtciodnu; // 加密密钥必须填写参数说明$db_host如果是远程数据库建议把127.0.0.1改成实际 IP同时确认 MySQL 允许远程连接GRANT ALL ON oa_db.* TO root%。最关键的$randkey——它是一个 26 位的固定字符串用来做密码散列和 Cookie 加密的盐值。这个值不是让你随便写的必须用资源里给的那串almvhcusrywkxvnzgdjtciodnu。如果随意改成别的轻则登录态无法保持重则已存储的密码散列全部无法校验等于把系统锁死。原文还有个容易忽略的步骤删除webmain/webmainConfig.php1。注意改名之后源码包里已经没有这个文件了但如果你的备份里有需要手动删除同时删除webmain/install整个目录。这是安全要求——install 目录如果保留攻击者可以重新执行安装脚本直接覆盖数据库和配置文件这是这类老系统最致命的漏洞。3.4 Linux 部署的文件权限与目录隔离Linux 下的坑比 Windows 多一个文件权限。老代码普遍喜欢直接写文件比如缓存、上传的附件如果 webroot 目录的属主不是 PHP 运行用户会出现「上传附件失败」「验证码图片无法生成」这类诡异问题。# 以 nginx php-fpm 为例php-fpm 运行用户是 www-data chown -R www-data:www-data /var/www/html/oa chmod -R 755 /var/www/html/oa # 上传目录建议放宽写权限一般是在 uploads/ 或 data/ 目录下 chmod -R 777 /var/www/html/oa/uploads 2/dev/null || true部署完成后浏览器访问http://127.0.0.1/用 admin / 123456 登录。如果一切正常左侧菜单会完整显示全部模块如果只显示空白页大概率是$db_pwd配错了或 randkey 没填——别急着换环境先回溯这两个参数。4. 流程与表单配置实战从请假审批流到自定义字段4.1 流程配置的底层逻辑模板、节点、实例三层模型这套系统的流程引擎是典型的表驱动设计核心概念可以拆成三层流程模板、流程节点、流程实例。流程模板定义「这个流程叫什么、有哪些审批步骤」流程节点定义「每一步谁来审批、满足什么条件跳哪一步」流程实例是一条真实的业务数据比如某员工提交的请假单在模板上跑出来的结果。打开源码中的流程相关数据表你会发现实际存储结构与概念一一对应-- 流程模板主表定义流程名称、状态、分类 SELECT * FROM flow_template WHERE status 1; -- 流程节点表定义节点顺序、审批人角色、条件分支 SELECT * FROM flow_node WHERE template_id 1 ORDER BY node_order;在界面上配置一个「请假审批」流程操作路径通常是流程配置 → 新建流程模板 → 依次添加节点。节点类型一般分三种发起节点、审批节点、抄送节点。审批节点需要设置审批人来源——可以指定某个角色如「部门经理」也可以指定表单字段如「申请人所在部门」这属于动态审批人的玩法老手常用新手建议先从固定角色配起。4.2 表单配置自定义字段的类型与校验流程要处理的数据由表单配置来定义。这个系统里表单配置相当于单独的一个设计器支持常见字段单行文本、多行文本、数字、日期、下拉选择、单选、多选、附件、人员选择器。每类字段都有几个关键属性字段类型核心属性典型用途单行文本长度上限、默认值、必填标题、单号数字最小值、最大值、小数位金额、天数日期日期格式、默认值为当天开始日期、结束日期下拉选择选项数据源、级联关系部门、城市附件文件类型限制、大小上限合同扫描件人员选择器可选范围部门/全员审批人、经办人配置表单时最容易忽视的是「字段与流程节点的绑定关系」。比如请假单里「请假天数」字段在流程第三个节点总监审批时应当是只读的不能让审批人乱改。这个权限粒度需要在表单字段配置里逐个设置该字段在哪些节点可编辑、哪些节点只读、哪些节点必填。源码层面其实就是一个字段权限表的维护但 UI 上做得比较隐晦需要把节点切换到对应步骤才能看到字段的编辑权限开关。4.3 实例化运行从提交申请到审批完成的数据流转配置好流程模板和表单之后员工提交申请时系统会创建一条流程实例记录表单数据作为实例的快照存储在业务表中。审批人登录后能从待办列表看到这条实例点开详情即是表单内容 历史审批记录。每个审批动作同意/驳回/撤回都会更新流程实例的当前节点指针和状态字段。在实际使用中我的习惯是在上线前先做一轮「全流程冒烟测试」自己建一个测试部门、测试角色跑一遍「发起 → 部门主管同意 → 总监同意 → 备案完成」的完整链路然后故意发起一条驳回记录确认节点状态回退正确。这个测试周期一般在半天到一天能筛掉流程配置里 90% 的坑比如节点顺序配反、审批人角色还没建好、字段权限未放行等。5. 部署与运行的常见坑现象、原因与解法5.1 首页 500 错误或空白页现象数据库导入成功、配置文件也改好了但访问首页直接白屏或 HTTP 500。原因90% 的情况是webmainConfig.php里的$randkey没填或者$db_pwd与实际数据库密码不一致导致连接失败但错误提示被关闭。剩下的 10% 是 PHP 版本太新5.3 把mysql_*函数的 E_DEPRECATED 提升到了 E_WARNING某些主机display_errors开启后直接崩掉。解决先开 PHP 错误显示临时排查——在 web 入口文件头部加ini_set(display_errors, 1); error_reporting(E_ALL);刷新看具体报错。如果是数据库连接失败回查配置文件如果是 randkey 未填导致密码校验错乱重置为那 26 位固定值并重启 PHP-FPM。这套系统不需要 Composer、不需要改伪静态报错一定在 PHP 语法或配置参数上。5.2 MySQL 高版本导致的「数据连接失败」与 SQL 执行中断现象MySQL 5.7/8.0 环境下身强 MySQL 连接失败或者导入 db.sql 时报错中断但前几张表已经导入成功。原因新旧 MySQL 的认证插件事。8.0 默认caching_sha2_password老 PHP 的mysql_connect不支持这种认证方式另外 db.sql 里的某些 SQL 写法比如TYPEMyISAM这种旧语法在 MySQL 5.7 会直接报警告并中断导入。解决用 MySQL 5.5 或 5.1 是正解如果必须用 8.0可以ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY password;改回旧认证方式。SQL 导入中断的补救删除库后重新导入前先检查 SQL 文件头部有没有SET SQL_MODE之类的兼容声明没有就自己在命令行加--force参数忽略非致命错误。5.3 中文乱码登录后页面全是「锟斤拷」现象数据库导入成功登录后菜单、模块名、系统设置全部乱码。原因Windows 命令行导入 SQL 时客户端默认字符集是 GBK导致把 UTF-8 源码当成 GBK 解码后写入数据库数据本身已损坏。解决这个没有后悔药只能删库重新导入。正确姿势一定是mysql --default-character-setutf8 oa_db db.sql。导入后在 PHP 配置文件里确认$db_charset utf8;如果有这个参数保证运行态连接也走 UTF-8。5.4 手机端访问样式错乱CSS 全部丢失现象PC 端正常手机浏览器打开页面是纯 HTML 不带样式或者图片路径 404。原因URL 重写或入口文件名不对。这套系统手机端和 PC 端共用一套资源但 CSS 路径通常是相对路径。如果你把系统装在子目录如/oa/而代码里写的是绝对路径/css/webmain.css那 HTML 会去域名根目录找 CSS自然 404。解决将系统装在域名根目录或独立子域名下不要放二级目录。或者统一入口用http://127.0.0.1/访问浏览器会自动解析相对路径。还有一种低频原因webimcss.css 或 cssm.css 里引用的字体文件font-awesome.eot的 MIME 类型没在服务器配置需要给 Nginx 加types { font/ttf ttf; }之类映射。5.5 忘了删 install 目录引发的「重新安装覆盖」现象初始化完成后没有删除webmain/install某天访问http://127.0.0.1/install/出现重新安装引导界面如果点下去数据库会被清空重建业务数据全部归零。原因安装脚本检查的是「配置文件和 install 目录是否同时存在」。配置文件已被改名激活但 install 目录还在安装脚本认为需要执行升级或重装流程。解决部署第一步就删。在 Linux 下执行rm -rf webmain/installWindows 下直接右键删除。如果已经误操作导致数据被覆盖只能靠数据库备份恢复。我的习惯是在部署完成后打包一份数据库转储放到服务器外作为第一个恢复点。6. 进阶玩法钉钉 / 企业微信接入与老 PHP 代码的兼容层如果你要把这套 OA 真正推给全员用手机端是绕不开的。虽然源码自带手机适配页面但员工不可能每天记一个网址。接入钉钉或企业微信的标准做法是把 OA 塞进对方的 H5 微应用框架里。以钉钉为例在钉钉开放平台创建一个 H5 微应用首页 URL 填http://your-domain/mobile.php再配一个可信域名员工就可以在钉钉工作台直接打开 OA。这里的关键是免登——钉端会往 URL 带一个authCode后端拿这个 code 去钉钉开放接口换用户身份再映射到 OA 系统的员工账号上。免登接口对接的底层逻辑如下?php // 钉钉免登对接示意用 authCode 换取用户身份 $code $_GET[authCode]; // 钉钉微应用带过来的授权码 $dd_access_token get_dingtalk_token($app_key, $app_secret); // 调用钉钉接口用 code 换用户 userid $user http_post(https://oapi.dingtalk.com/topapi/v2/user/getuserinfo, array( access_token $dd_access_token, code $code )); if ($user[errcode] 0) { $oa_username $user[result][name]; // 钉钉名字需与 OA 账号关联 // 根据 $oa_username 查 OA 的 sys_user 表创建会话 $_SESSION[user] $oa_username; header(Location: index.php); }这个接入方案我实际落地过两次最大的麻烦点在于账号映射——钉钉用户表里的员工姓名和 OA 里的姓名要保持一致或者做一个「钉钉 userId ↔ OA uid」的映射表。建议先导出两份名单做比对把差异项在入职流程里统一掉不然用户提了免登申请还要走一遍手工绑定体验会打折。再说 PHP 兼容补丁。如果你的服务器只能装 PHP 7.4比如用了较新的云主机镜像老代码的mysql_*函数会直接 fatal error。有个低成本方案是写一个兼容 shim 文件?php // mysql_* 兼容层放到入口文件里 require 即可 if (!function_exists(mysql_connect)) { function mysql_connect($host, $user, $pwd) { $conn new mysqli($host, $user, $pwd); return $conn; } function mysql_select_db($db, $conn null) { $conn $conn ?: new mysqli(127.0.0.1, root, ); return $conn-select_db($db); } function mysql_query($sql, $conn null) { $conn $conn ?: new mysqli(127.0.0.1, root, ); return $conn-query($sql); } function mysql_fetch_assoc($result) { return $result-fetch_assoc(); } // 其余 mysql_* 函数按同样方式逐个补全 }注意这样只能解燃眉之急——mysqli 和 mysql 的 API 略有差异某些老代码里的mysql_fetch_array($result, MYSQL_ASSOC)第二参数是不存在的shim 里要兼容。更稳妥的做法是全局搜索源码中的mysql_前缀写脚本批量替换为mysqli_并同步修改参数顺序。但这属于较大改造非必要不推荐还是找一台老环境最省事。部署验证的最后一步我会写一个检查清单数据库表数量正确、admin 能登录、能新建流程模板、能提交一条请假申请、待办列表能收到通知。走完这五步这套 OA 才算真正交付。说到底老代码的价值在于它能稳定解决 80% 的通用办公需求剩下的 20% 需要你理解它的脾气。印象最深的是有一次客户环境 PHP 版本装成了 7.1我坚持让他们降到 5.2这十分钟的坚持换来的是后面两年没出过一次运行时错误。从那以后我每次接手老 PHP 项目都强制先确认 PHP 版本与mysql_*函数可用性再谈别的优化。希望这些经验帮到你下载源码后按上面的顺序一步步走这套系统能比你想的更稳。本文还有配套的精品资源点击获取