40人小公司从零搭一套OA+手机App,我是怎么过的坑(全过程实战)
> 本文:40人左右的企业,没有纸质证书,老板一人,搞了个OA。我从零开始,把OA网页、Flutter App、iPhone免钱方案全搞定。这篇文章说完了踩过的坑、做过的取舍,给同样在中小企业做内部系统的人参考。
一、背景:为什么公司要自建OA
公司规模40人左右,内部管理靠纸质表格、微信群、Excel排班。问题一堆:
- 请假单要跑几个办公室签字,老板不在就卡住
- 审批记录靠翻聊天记录,对不上账
- 订餐靠群里报,统计全靠人工
- 扫码核销没有工具
当时需求很直接:不做大而全的商用OA(太贵、太重、员工不配合),就要一个"打开就能用、手机能操作"的轻量系统。
需求范围定下来:
- 请假/审批流:多模板、自动流转、线上审批
- 订餐:每天自动统计、短信提醒
- 加班管理、公告消息
- 扫码核销(手机场景)
- 手机App(安卓为主,iPhone也要能用)
二、技术选型:不追新,只求稳
环节 | 选型 | 理由 |
后端 | Python Flask | 单人可维护 |
数据库 | SQLite 起步 | 数据量小,够用 |
前端 | 服务端渲染原生HTML+JS | 不引框架,老电脑也流畅 |
手机App | Flutter | 一套代码双端 |
部署 | 云服务器ECS + Nginx + HTTPS | 内外网都能访问 |
分发 | 自建下载页 + 二维码 | 不上应用商店,成本为零 |
核心思路:一套代码、一个域名、一个后台,员工只用一个入口。
三、部署架构:三台机器分工 + 一台云服务器
3.1内网三台机器分工
机器 | 职责 |
19端 | 生产环境(日常业务) |
98端 | 测试环境(新功能验证) |
83端 | 热备(实时同步生产) |
生产代码在测试机验证通过,再部署到生产机,热备机实时同步,出问题可以快速切换。
3.2云端服务器
对外统一走云服务器,Nginx 反向代理 + HTTPS:
https://oa.域名 → 5003 网页端 + API
https://order.域名 → 5000 订单系统
https://api.域名 → 5000 开放接口
SSL 证书 Let's Encrypt 自动续期,不用人工管。
四、网页端核心设计
4.1表单模板 + 流程模板分离
审批流最核心的设计:表单模板定义"填什么",流程模板定义"谁来批"。
- 请假类型、审批规则(>3.5天自动加批老板)全部模板化
- 年假最小单位0.5天、其他假最小1小时(0.125天)
- 加新的审批类型 = 加一个模板,不动代码
4.2审批全生命周期
申请 → 提交 → 主管审批 → 老板审批 → 通过/驳回 → 电子单据(PDF)
支持:撤回、驳回重提、指定审批人、审批记录留痕。
4.3扫码核销的HTTPS坑
网页端调摄像头做扫码核销,浏览器必须HTTPS才能调摄像头权限。所以单独开一个HTTPS端口(5004)专门给扫码页,其他页面走HTTP(5003)。这个坑不踩不知道,一踩要改半天。
五、Flutter App:从零到正式发布
5.1为什么选Flutter
- 一套代码出安卓+iOS
- 打包快,改动及时分发
- 正式签名后可覆盖安装
5.2固定连云端
App 固定连接 https://oa.域名/api/v1,不依赖内网,家里也能审批。
5.3正式签名:易被忽视的坑
- 用 keytool 生成 PKCS12 证书(.p12)
- 有效期25年,配置 key.properties 签名
- 证书+密码必须多重备份,丢了App就覆盖不了,只能卸载重装(同事已装的会被重置)
5.4版本号两处同步的坑
登录页底部显示 "版本 vX.X.X",这个和 pubspec.yaml 的 version是两处。漏改一处,同事反馈"版本号没变",排查半天。
5.5发版SOP(固定流程)
改代码 → flutter analyze → 打包release → 本地验证
→ 上传服务器 → 更新下载页 → 同事扫码下载
APK 命名带版本号(OA_App_v1.5.0_正式版.apk),旧版删除防混淆。
六、iPhone怎么办:不花钱的PWA方案
老板和同事都有iPhone。原生iOS App需要Mac + 苹果开发者账号(年费688)+ 上架审核,公司不想花这个钱。于是用了PWA:把网页版做成"可安装到主屏幕"的Web App,用起来跟App一样。
6.1需要做的东西
项目 | 说明 |
manifest.json | 配置"全屏、独立窗口" |
apple-touch-icon | iPhone主屏幕图标 |
启动画面 | 6种尺寸适配不同iPhone |
theme-color | 状态栏颜色 |
安装引导页 | 图文+二维码教同事加主屏幕 |
6.2关键meta标签
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="OA">
<meta name="theme-color" content="#3e2723">
<link rel="apple-touch-icon" href="/static/pwa/apple-touch-icon-180.png">
6.3启动画面适配
iPhone机型太多,启动画面按尺寸用 media 查询匹配,覆盖6种主流机型(750x1334 / 1125x2436 / 1170x2532 / 1242x2688 / 1290x2796 / 1284x2778)。
6.4下载页双Tab分流
- 安卓:显示APK下载二维码
- iPhone:显示安装指南
- 微信内打开:提示"浏览器打开"(微信不让下载)
- iOS设备:自动切到iPhone面板
同事打开下载页,iPhone自动显示"添加到主屏幕"指引,看起来就是原生App。
七、踩坑总结(每条都值钱)
- 微信内无法下载APK → 下载页做微信提示引导
- 扫码核销必须HTTPS → 单独开HTTPS端口
- APK版本号两处不一致 → 发版清单化
- 签名证书丢失无法升级 → 多重备份
- PWA不更新 → 设置 scope /,发版提醒同事刷新
- 旧版本APK混淆 → 命名带版本号,删旧版
- 模板改了不生效 → 改模板必须重启服务+验证
八、架构演进:从"能跑"到"稳定"
第一步:单体Flask + SQLite,够用就行
第二步:云服务器 + Nginx反代 + HTTPS + 热备
第三步:App端 + PWA + 下载体系 + SOP化
每一阶段都围绕"同事用得顺、老板看得见"推进,没有为了技术而技术。
九、给同样处境的人的建议
- 别一上来就上大框架,SQLite能跑先跑
- 审批流模板化设计,以后加流程只加模板
- App签名证书第一时间备份,丢了就完蛋
- 发版清单化、SOP化,不要靠记性
- iPhone用户别急着买Mac,PWA方案0成本先用
如果你也在做类似的企业内部系统,欢迎评论区交流。踩过的坑、走过的路,都在这里了,希望帮你少走弯路。
公司真实搭建,欢迎讨论 !
