ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ever-gauzy开源ERP/CRM深度解析:架构、部署与二次开发实战

ever-gauzy开源ERP/CRM深度解析:架构、部署与二次开发实战 做开源ERP/CRM选型的人多半会在某个时间点撞见ever-gauzy这个名字。它经常和另一个老项目Gauzy混在一起但只要clone过仓库就会发现ever-gauzy不是简单改了名字而是Ever团队用TypeScript全栈重做的新一代开源业务管理平台。我当时接手团队内部管理系统时老板给的预算接近零需求倒是挺长一串客户资料、报价、报销、项目工时、月底算钱。看了一圈商业软件要么太贵要么不能改最后落到ever-gauzy上。用下来最大的感受是它不像某些号称开源的ERP只有一个空壳而是把一个能够落地的CRM、会计薄、项目工时和报表系统都塞进了同一个代码库而且底层的多租户、权限、国际化、桌面端这些能力完全可以当作研发基座来用。这篇文章不打算照着官网翻译功能清单而是从我实际部署和二次开发的角度把ever-gauzy的定位、技术架构、核心模块、部署方式和踩过的坑一次讲清楚。适合正在做技术选型的负责人、想基于开源ERP做二次开发的工程师以及帮小团队搭业务系统的独立开发者参考。1. ever-gauzy到底是个什么项目1.1 项目背景从Ever到Gauzy再到ever-gauzy要理解ever-gauzy得先分清三个名字。Ever是公司名Gauzy是它早期推出的开源ERP/CRM产品ever-gauzy则是当前迭代中的代码仓库名和产品名。官方对它的定位是一套开源的业务管理平台覆盖客户关系、销售流程、项目协作、会计、发票、人力资源等内容。从代码仓库能看到它有一套非常典型的全栈Monorepo结构前端是Angular后端是NestJS桌面端用Electron打包数据层以TypeORM为基础支持PostgreSQL和SQLite等数据库。可以说Ever团队把过去做外包和企业软件的经验都沉淀在了这个项目里所以功能边界比很多同类开源项目要宽很多。很多人第一次看到这个项目会误以为它只是一个CRM实际上它是一个带着CRM能力的ERP雏形。这也解释了为什么仓库里会有大量的实体类比如Customer、Deal、Invoice、Expense、Timesheet、Organization等等。我的理解是Ever团队想把一个中型公司日常运转涉及到的数据模型全部开源出来让使用者不需要从零设计数据表。对于创业团队来说这是非常大的一个起点优势等于有人已经帮你把二十几张核心业务表的关联关系理顺了。1.2 它解决了什么问题我在实际使用中总结下来ever-gauzy解决的核心问题有这么几类。第一是业务数据割裂的问题很多小团队用Excel管客户、用另一个工具记工时、再用第三个工具开发票数据对不上是常态ever-gauzy把这些数据模型放在同一套系统里天然解决了关联一致性的问题。第二是私有化部署的问题商业SaaS型CRM每年按人头收费数据还在别人服务器上对于有合规要求或者数据敏感的企业来说自部署几乎是唯一选择ever-gauzy允许你在自己的服务器上完整运行。第三是二次开发空间的问题开源最大的好处是能改你可以把报价审批流程改成符合自己公司业务的样子而不是反过来迁就软件。当然它也不是银弹。ever-gauzy的模块很多对应的是更高的学习成本和配置成本指望拉起来就能用是不现实的需要根据自己公司的业务做取舍。我的建议是先只启用客户、线索、项目工时和报销这几个核心模块跑顺了再加其他功能不要一上来就把所有按钮都打开。2. 技术架构深度拆解2.1 后端选型NestJS加TypeORM的组合让我省了不少事ever-gauzy的后端选择了NestJS这是近几年Node.js生态里非常成熟的企业级框架最吸引人的一点是模块化组织和依赖注入机制。你去看这个项目的代码会发现每个业务域都对应一个Feature Module比如InvoiceModule、EmployeeModule、ExpenseModule每个模块里有Controller、Service、Entity、DTO各司其职。这种组织方式让一个上万行代码的项目不至于乱成一锅粥新成员上手时也能按图索骥。我自己的体会是当你需要在现有基础上加一个业务模块时只要照着已有模块复制一套结构再跑到AppModule里注册一下基本就成了。数据层用的是TypeORM配合装饰器来定义实体和字段关系。比如一个Employee和Organization之间通常会有多对一关联在代码里就是用ManyToOne装饰器直接声明的改起来非常直观。TypeORM支持数据库迁移在ever-gauzy里也定义了Migration的目录结构这意味着你可以把数据结构变更纳入版本管理而不是跑到数据库客户端里手工改表结构。生产环境我强烈建议用PostgreSQL而不是SQLite虽然SQLite本地跑起来很轻快但并发写入和事务能力差很多多人同时操作报销和工单时容易出问题。2.2 前端Angular和桌面端Electron的选择逻辑前端用Angular而不是React或Vue这个选型本身是有取舍的。Angular是一个偏重工程化的框架自带依赖注入、路由、表单校验、HTTP客户端等一系列能力和NestJS的架构风格高度一致。业务系统本质上就是大量的表单和表格Angular的响应式表单在复杂业务场景下非常好用而且项目中大量使用了RxJS来处理异步状态对于实时仪表盘和数据联动这类需求非常顺手。如果你是第一次接触这个项目建议先理解Angular的模块和依赖注入机制否则看代码会有点懵。Electron桌面端是另外一个很有特色的部分。桌面端不是简单的Web页面套壳它的价值在于可以本地运行适合那些不想把数据放到公网服务器的团队。比如我们团队当时把整个系统装在一台离线电脑上通过桌面端跑在局域网里员工填报工时和报销根本不需要暴露到公网这对数据隐私是很大的加分项。Electron的坑主要是打包体积和分发但在ever-gauzy里已经内置了一套构建流程不需要自己从零配置。2.3 数据库、缓存和多租户设计ever-gauzy对数据库的支持既有PostgreSQL又有SQLite官方同时提供了一套可配置的环境变量来切换数据库类型。实际部署时我建议开发环境用SQLite快速跑起来生产环境则切换到PostgreSQL。多租户是这套系统非常核心的一个设计通俗讲就是一套系统里可以隔离多个互不干扰的组织每个组织看到的数据是独立的。这在做SaaS服务或者集团内部多公司管理时非常关键底层实现通常是通过数据查询时自动带上的TenantId来完成的。缓存和任务调度在正式环境同样绕不开。项目里集成了类似Redis这样的缓存组件以及定时任务机制用来处理邮件队列、后台统计这类耗时任务。第一次部署时我忽略了这些组件的配置结果定时任务一直没跑起来后来发现是Worker进程没有启动。所以我的建议是不要只看API进程和前端进程把后台Worker的启动命令也纳入进程守护否则很多异步功能会静默失效。3. 核心功能模块逐项拆解3.1 客户关系与销售流程管理ever-gauzy在CRM上的底气是不错的它不是一个简单的通讯录工具而是把客户、线索、商机、合同、发票串成了一条完整的销售链路。你可以记录一个线索的来源把它转化为客户再关联到具体的商机和报价单后续的发票和回款也能挂在同一条业务线上。这样当老板问某个大客户的回款情况时不需要去翻Excel直接打开客户详情页就能看到从销售到回款的闭环数据。实际使用中我特别推荐先配置好销售管道里的阶段比如“初步接触、需求确认、方案报价、商务谈判、赢单、输单”。每个Deal挂在对应的阶段上系统可以自动生成销售漏斗视图方便管理层判断接下来几个月的业绩趋势。这块的报表能力虽然不是最重的但对于大多数中小团队来说已经完全够用。需要提醒的是CRM模块里很多字段是可自定义的但最初不要加太多不然团队填起来有负担数据反而收集不全。3.2 财务、报销与发票的日常操作财务模块是ever-gauzy比较让我惊喜的部分它没有停留在记账这种表面功能上而是把发票、收款、报销、费用和预算关联到了一起。员工可以发起一笔报销上传发票照片填写费用类别和对应项目然后走审批流。系统会自动生成应收和应付的统计财务报表可以按月份、项目、部门等多维度查看。在传统ERP里这些功能往往藏在很深的菜单里而ever-gauzy把它们做得相当直白普通员工不需要培训太久就能上手。发票模块支持生成PDF并发送给客户也支持记录多币种以及税费。我们当时有部分海外客户系统内置的多币种功能帮了大忙。我建议财务人员在初始化时把税号和默认税率配置好否则后续开票时会需要逐张修改。报销流程里把审批人配置清楚非常关键ever-gauzy的权限模型允许指定某个角色的用户作为审批人如果这一步没配好员工提交的报销单会一直停在待审批状态给人留下系统不好用的印象。3.3 项目、任务与工时追踪工时追踪是ever-gauzy里我非常喜欢的一块也是很多商业软件单独收费很高的功能。员工可以在工时表里记录每天在哪些项目上花了多少时间可以按任务标签来区分也可以集成桌面端进行本地计时。项目管理者能实时看到各个项目的工时投入从而判断哪些项目超支了、哪些成员被过度分配了。结合团队成员的成本数据系统还能把工时换算成人工成本这对项目利润率核算是极有价值的。任务管理本身足够轻量适合和团队现有流程结合起来用。我们当时没有把ever-gauzy当作唯一的项目管理工具而是把它作为财务和工时数据的底座项目管理仍然用看板工具再通过API把工时数据同步过去。这样既不影响团队习惯又能拿到准确的成本数据。如果你直接把ever-gauzy的任务功能开放给全员可能遇到一些适应性阻力因为相比专用项目管理工具它的任务交互相对传统但这不影响它的数据价值。3.4 报表、仪表盘与智能助手做管理系统的最终目的是辅助决策ever-gauzy在报表上提供了不少预置仪表盘比如销售漏斗、收支统计、项目盈亏和人员开销。这些仪表盘的颗粒度可以按公司维度看也可以按项目维度拆右上角的时间筛选器能让你快速查看周报、月报、季度数据。当然如果需要的报表形态非常特殊也可以自己写查询因为数据表是开放的直接用SQL连接数据库分析完全可行。项目里还有一个Ever AI的模块目前更多表现为一个智能助手入口可以用来辅助查询数据和生成内容。我的理解是它更像是把AI能力嵌入业务系统的探索性尝试如果你有自己训练或者接入大模型的需求可以把这部分当作参考实现来用。对于普通使用者来说核心价值仍然是结构化的报表和自由查询不要对AI部分期待太高。3.5 多语言与国际化ever-gauzy的多语言支持做得比较到位界面文案和部分业务数据都支持国际化可以在运行时切换语言。这对有海外员工或者跨国业务的团队来说很实用。语言文件本身是可编辑的资源文件如果你发现某些专业术语的翻译不够准确可以直接修改并重新构建这在商业软件里基本是不可能实现的自由度。我当时调整了一版中文术语把“Invoice”统一改成了“账单”完全不影响系统稳定性。4. 从零开始部署本地开发与Docker两条路线4.1 部署方式优缺点对比ever-gauzy提供了两种主流的部署方式直接在服务器上按源码构建运行和使用Docker容器化编排。两种方式各有适合的场景我整理了一张表方便你对照选择。对比项源码部署Docker部署上手门槛需要安装Node环境与数据库步骤较多相对简单一条命令拉起整套环境自定义能力修改源码后重新构建方便需要自己重新打镜像资源占用文件相对精简镜像会占用更多磁盘生产环境稳定性依赖手动管理进程容器编排更容易管理依赖推荐场景本地开发、深度定制快速试用、生产部署我个人的建议是刚开始试用先在个人电脑上用源码方式跑起来把代码结构看明白。等确定要上生产了再用Docker Compose把数据库、API、前端、Worker这些服务编排起来这样后续扩容和备份也方便。4.2 源码方式本地启动假设你已经装好了Git和Node.js第一步就是克隆代码仓库并安装依赖。项目默认使用yarn作为包管理工具安装依赖前我建议先确认Node版本是否在项目要求的范围内太新或太旧的版本在编译Electron或某些原生依赖时都会报错。git clone https://github.com/ever-co/ever-gauzy.git cd ever-gauzy yarn install cp .env.example .env安装依赖会比较久因为需要拉取Angular和Electron相关的大量包耐心等待即可。如果是在国内网络环境Electron下载偶尔会失败可以配置镜像源来解决。依赖安装完成后把环境变量文件里的数据库连接信息改成你自己的PostgreSQL配置同时确认Redis连接地址是否正确。然后启动API和前端yarn start:api # 另开一个终端 yarn start:web默认情况下API服务会监听在3000端口前端开发服务器会监听在4200端口浏览器打开4200端口就能看到登录页了。初次启动时系统会自动执行数据库迁移并初始化基础数据这个过程如果报错多半是数据库连接串或者用户权限的问题逐项排查即可。4.3 Docker Compose方式运行如果你想快速看效果不想折腾本地环境的依赖那Docker Compose是最合适的。项目仓库里提供了生产用的编排文件直接执行下面的命令就能拉起整套环境docker-compose up -d执行完成后用docker ps查看容器状态正常情况下应该有API、前端、数据库和Worker这几个核心容器运行。我第一次用Docker方式部署时踩过一个比较隐蔽的坑宿主机端口和容器端口映射冲突。如果3000或4200端口被占用docker-compose里的端口映射就会失败改一下宿主机侧端口就好。比如把前端映射成127.0.0.1:8080:4200把API映射成127.0.0.1:8081:3000这样同一台机器上可以并存多个实例。4.4 初始化配置与首次登录不论用哪种方式启动首次登录都需要用到初始化生成的管理员账号默认账号密码一般会记录在官方文档或者启动日志里。登录后的第一件事是创建自己的组织填写组织名称、默认货币和时间时区。这一步非常重要因为在多租户架构下所有后续数据都归属于这个组织。如果这里配错了后续再调整需要改数据库非常麻烦。接下来需要配置邮件服务否则系统无法发送邀请邮件和通知。开发环境可以先用一个测试用的SMTP账号生产环境建议使用企业邮局的SMTP配置。邮件服务配置好后邀请团队成员注册账号给他们分配对应的角色权限。我这里特别提醒一点ever-gauzy的权限点非常细给普通员工配置时不要图省事直接给管理员角色测试环境无所谓生产环境一定按最小权限原则来分配。5. 二次开发实战给客户档案增加一个自定义字段5.1 模块组织和扩展思路ever-gauzy的设计思路注定了它不是一套让你用来死记硬背操作路径的软件它更希望你把它当成一个开发平台来使用。我在做二次开发时发现扩展一个业务字段或者新增一个模块的路径非常清晰核心思路就是顺着现有的Feature Module走。假设你需要在客户档案里增加一个“客户来源渠道”的字段大概需要改动后端实体、数据库迁移、前端表单和列表展示以及API校验逻辑四个部分。动手之前先建议你看一下apps/api/src/app这个目录下的模块注册方式观察一个现有模块从Entity到Controller再到Module的完整链路。理解了这个链路后面的增删改其实都是一种模式。还有一点需要注意ever-gauzy的API同时支持GraphQL和REST两种方式你在参考文档时一定要先确认自己看的是哪种风格的示例别混着抄代码。5.2 后端实体和接口扩展定义实体是第一步。找到客户对应的实体文件在类中增加一个普通字段即可比如Column({ nullable: true }) customerSource?: string;字段定义好之后需要生成并运行数据库迁移。ever-gauzy使用TypeORM迁移机制一般通过npm脚本或者命令行来生成迁移文件。迁移文件就是一段可以上下执行的结构变更脚本它会确保数据库结构和实体保持一致。一定要注意如果只改实体不执行迁移运行时会报字段不存在的错误。生成迁移后用启动命令让迁移执行或者手动运行迁移命令。接口层一般不需要额外改动因为现有模块的Controller已经提供了创建和更新的通用接口新字段会随实体自动支持。如果字段需要参与复杂校验可以在对应的DTO文件里加入校验规则比如使用管道的方式限制输入长度或必填状态。我在实际开发中习惯把所有可选字段都先设成nullable: true等功能稳定后再收紧为必填这样能减少中途回滚的成本。5.3 前端页面接入后端字段准备好了接下来是前端表单。在Angular项目中客户表单是一个响应式表单控件组你只需要在对应的表单组件里增加一个控件实例并在HTML模板中添加对应的输入框。如果字段需要支持下拉选择还要在代码中预置选项列表。表单提交前确保控件的值已经绑定到了提交的DTO上否则后端虽然能接收字段前端却不会把它发过去。列表展示部分需要在客户列表页面增加一列或者增加一个扩展卡片来显示这个新字段。这里最需要注意的是Angular基于TypeScript的强类型如果DTO类型里没有声明新字段模板编译时就会报错。所以每加一个字段要检查对应前端模型类型、表单类型和提交DTO三处。改完代码本地起开发服务器测试一遍新增客户和编辑客户的完整流程重点看字段值刷新后是否还能正确回显。5.4 权限与数据安全注意事项每次扩展功能时都值得停下来问一句用户权限是否覆盖到了这个新字段。ever-gauzy的权限控制可以精确到接口级别也可以控制角色能否查看某些数据。对于客户来源这类普通字段通常不需要额外配置但如果扩展的是合同金额、人员薪资这类敏感字段就需要在Roles和Permissions里认真核对防止普通员工通过浏览器调试工具看到隐藏API返回的数据。这一点是很多新手做二次开发时容易忽略的。另外如果你扩展的字段要在多租户的数据隔离中生效务必检查新实体是否带有组织ID或租户ID的关联。ever-gauzy的底层查询默认会做数据范围过滤但如果你新增的实体没有正确关联组织就可能出现跨租户看到数据的问题。我在测试多租户场景时通常直接创建第二个测试组织来验证数据隔离确认A组织的账号看不到B组织的记录。6. 部署与二次开发中的典型问题排查6.1 高频问题速查表我把实际使用中遇过或者社群中常见的高频问题整理成了下面的速查表方便你直接对照处理。问题现象常见原因排查与解决思路启动时提示无法连接数据库数据库连接串配置错误或端口未开放检查.env中的数据库地址、用户名和密码确认数据库服务已经启动Angular编译内存溢出Node默认堆内存不足在构建命令前设置NODE_OPTIONS提高内存上限Electron安装失败或下载缓慢安装包下载源不稳定配置Electron镜像源后重新安装依赖定时任务不执行Worker进程未启动检查后台Worker服务状态保证其正常运行邀请邮件发送失败SMTP配置有误或端口被封尝试更换SMTP端口或使用企业邮局服务登录后部分菜单空白角色权限没有配置完整给当前账号分配对应模块的访问权限多租户数据串号新定制实体未关联组织ID检查实体中是否包含organizationId与tenantId字段这张表只是起点实际部署中每个团队遇到的网络环境和服务器状态都不同建议遇到问题先看日志尤其是API进程的日志大多数问题在日志里会直接给出报错信息。6.2 性能与稳定性优化建议ever-gauzy在中小规模团队下跑起来毫无压力但如果组织数据增长很快有几点建议可以提前做。API数据库连接池参数要根据访问量调节默认配置偏保守并发高时容易出现连接等待。前端构建产物建议交给Nginx这类静态服务器托管并开启Gzip压缩能明显减少首屏加载时间。PostgreSQL的定期清理和索引维护也别忘了因为报表查询往往涉及多表联查没有合适索引时会很慢。备份策略上除了数据库定时备份建议把上传的附件目录也纳入备份范围。我见过有人只备份数据库不备份附件结果恢复后发现所有发票PDF和头像图片全丢了。如果你用Docker部署备份数据库可以用docker exec进入容器执行pg_dump也可以直接备份数据卷目录各有优劣关键是形成一个固定流程并定期演练恢复确保关键时刻拿得出来。6.3 版本升级和代码二次开发的长线配合如果你在ever-gauzy源码基础上做了不少定制版本升级会是比较头疼的话题。我的建议是尽量避免直接修改上游核心代码能通过新增独立模块实现的功能就新增模块这样上游更新时可以更平滑地合并。如果实在要改核心代码务必把改动点集中管理并在仓库里写好注释方便升级时逐项评估。我在团队里建立了一条规矩所有对上游的改动都在代码注释里标明改动原因和日期否则几个月后根本想不起来当初为什么要改。版本升级前先在测试环境完整跑一遍数据迁移和核心业务流程尤其是发票、报销这类涉及审批和金额的功能一定不能跳过回归测试。开源项目迭代速度快有时接口参数变了或者数据库字段调整了及时跟踪上游的Release说明能避免很多坑。7. 从选型到落地的一点个人体会这套项目我在两三个不同的业务场景里用过每次感受都不太一样。第一次是团队内部管理只用它管客户和工时顺手又接了报销效果很好第二次是想完全替代商业财务软件发现还需要配置很多规则和做报表定制工作量明显变大。所以我现在的判断标准是如果你需要一个可自主掌控、能长期积累业务数据的数字底座ever-gauzy非常合适如果你只是想找一个开箱即用的记账软件那它可能反而不如一个轻量商业工具直接。最后再分享一个小技巧把部署文档和初始化步骤写进自己团队的Wiki里不要依赖记忆。即使是你自己搭的环境三个月后回来看也未必记得每一个配置项是做什么用的。ever-gauzy的官方文档已经算得上详细但每个团队的服务器、网络、邮件服务都不一样一份属于你自己环境的记录比任何通用文档都更值钱。
返回列表