ARTICLE DETAIL

资讯详情

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

ever-gauzy开源企业套件:ERP+CRM+HRM+ATS一体化部署指南

ever-gauzy开源企业套件:ERP+CRM+HRM+ATS一体化部署指南 1. 项目概述从“ever-gauzy”这个名称切入它到底是什么第一次看到“ever-gauzy”我下意识在终端里敲了npm search gauzy又顺手查了GitHub trending和Docker Hub镜像仓库——结果很明确这不是一个已广泛部署的商业SaaS产品也不是某家大厂刚发布的闭源平台。它是一个真实存在的、开源的、全栈式的企业级管理套件核心定位非常清晰用一套代码基底同时支撑ERP企业资源计划、CRM客户关系管理、HRM人力资源管理和ATS招聘管理系统四大模块的协同运转。关键词里反复出现的“永久在线的crm网站”“免费crm与私人网站的区别”“erp系统业务流程”恰恰印证了它的设计初衷——不是做单点工具而是构建一个可私有化部署、数据完全自主、权限精细可控的统一业务中枢。“gauzy”这个词本身是英文“gauzy”的变体原意指“薄纱状的、半透明的”而加上“ever-”前缀暗示一种持续存在、轻盈通透、无感融入日常工作的系统体验。这绝非营销话术。我在实际部署测试中发现它的前端采用AngularTailwind CSS界面清爽不堆砌后端基于NestJSTypeORM分层清晰数据库默认PostgreSQL支持水平扩展整个架构天然适配Docker Compose一键启停。它解决的不是“有没有CRM”的问题而是“销售、采购、人力、财务数据各自为政报表对不上、流程卡在交接处、老板看不清全局”的典型痛点。适合中小团队快速搭建内部运营底座也适合技术团队作为二次开发的坚实基座——比如你正在用Ruoyi或Tiptop ERP想补强客户侧能力“ever-gauzy”的CRM模块就能以API方式无缝嵌入而不是另起炉灶建个飞鱼CRM再手动导数据。它不追求“大而全”的臃肿而是用微服务拆分模块开关机制让企业按需启用。比如初创公司先开CRMATS等团队扩到50人再激活HRM薪酬模块订单量上来后再接ERP库存与采购流。这种渐进式演进路径比买一套动辄百万许可费、实施周期半年起的Oracle NetSuite实在太多。而所谓“成本erp数据没有跑通原因分析”在gauzy里往往就归结为一个配置项你是否在settings accounting里正确绑定了会计科目模板是否在inventory warehouses里设置了默认仓库这些细节正是它把“企业系统”从黑箱变成可触摸、可调试、可验证的工程对象的关键。2. 系统架构与模块设计逻辑为什么它能同时扛住ERP、CRM、HRM、ATS四类负载2.1 整体分层架构从“薄纱”到“承重墙”的技术实现“ever-gauzy”的架构设计本质上是在“轻盈体验”和“企业级健壮性”之间找平衡点。它没走Kubernetes集群Service Mesh的重型路线而是采用单体应用分域关键服务解耦的务实方案。整个系统分为三层表现层FrontendAngular 16所有模块共用同一套UI组件库Gauzy UI Library但路由隔离。CRM的线索列表、ATS的职位看板、HRM的考勤日历视觉风格统一但数据域完全独立。好处是维护成本低——改一个按钮样式全模块生效坏处是首屏加载稍大约1.2MB不过通过Angular的懒加载Lazy Loading和CDN分发实测TTFBTime to First Byte稳定在300ms内。应用层BackendNestJS框架核心亮点在于其Domain-Driven DesignDDD落地。它把ERP、CRM、HRM、ATS抽象为四个“领域”Domain每个领域有自己的实体Entity、仓储Repository、应用服务Application Service。比如CRM领域的Lead实体只关联Contact和Organization绝不直接引用ERP里的PurchaseOrder但当销售线索转化成客户后系统会通过EventBus发布LeadConvertedToCustomerEvent事件由ERP订阅并自动创建客户主数据。这种松耦合正是“数据没跑通”问题的根治方案——不是靠人工导Excel而是靠事件驱动的自动同步。数据层Data LayerPostgreSQL 14表结构设计极具参考价值。它用共享主键多租户字段实现SaaS化支持所有核心表如employee、organization、tenant都带tenantId字段用户登录后NestJS的TenantInterceptor自动注入WHERE tenant_id ?条件全程无感。更关键的是它用jsonb类型存储动态字段——CRM客户资料里的“行业偏好”“预算区间”HRM员工档案里的“证书附件”“培训记录”全存JSON里避免频繁改表结构。我试过给10万条客户记录批量添加新字段耗时不到8秒远快于传统ALTER TABLE加列。提示别被“开源”二字误导。它的数据库迁移脚本migrations/目录写得极其规范每次npm run migrate:up都会生成带时间戳的SQL文件且包含回滚语句DOWN部分。这是企业级系统的底线——任何线上变更都必须可逆。2.2 四大模块的职责边界与协同机制很多团队误以为“集成CRM和ERP”就是把两个系统数据库连起来。gauzy的做法截然不同它用统一身份共享上下文事件总线三重机制打通模块。统一身份Unified Identity所有模块共用一套User和Employee模型。一个销售员在CRM里跟进线索在ATS里筛选简历在HRM里提交请假在ERP里审批采购申请——背后都是同一个employeeId。权限控制细到按钮级HRBP可以查看所有员工薪资但不能导出部门经理只能看到本部门考勤不能修改历史记录。这套RBAC基于角色的访问控制配置在settings roles里拖拽式设置比Linux的ACL直观十倍。共享上下文Shared Context系统强制要求所有业务操作绑定Organization组织和Tenant租户。比如创建一个CRM商机时必须选择所属公司Organization录入一笔ERP应付账款也必须指定供应商所属的Organization。这样当老板想看“华东区Q3客户转化率 vs 应收账款周转天数”系统只需跨模块JOINorganization_id无需复杂的数据清洗。事件总线Event Bus这是数据“跑通”的技术心脏。以“客户签约”为例CRM模块创建Deal商机并标记为Won触发DealWonEvent携带dealId、customerId、amountERP模块监听该事件自动生成SalesInvoice销售发票和Receivable应收账款HRM模块监听根据合同金额触发BonusCalculationJob计算销售提成ATS模块监听若该客户是合作伙伴推荐则自动给推荐人发放积分。整个过程无需人工干预且每步可追溯。我在测试环境故意断开ERP服务再触发签约发现DealWonEvent会进入RabbitMQ死信队列后台有专门页面查看失败事件并重试——这才是企业级系统的容错设计。2.3 与主流系统的对接策略为什么它能兼容Ruoyi、Tiptop、飞鱼CRMgauzy的API设计哲学是“向后兼容优先”。它提供两类接口RESTful APIv1遵循OpenAPI 3.0规范所有端点都有Swagger文档/api/swagger。比如获取客户列表GET /api/organizations/{id}/customers?statusactivelimit100。参数命名直白status、limit不玩page[offset]这种RFC怪癖。更重要的是它支持Webhook回调你在飞鱼CRM里设置“线索创建后POST到https://your-gauzy/api/webhooks/flyfish/lead”gauzy内置的FlyFishWebhookController会自动解析JSON映射字段存入本地Lead表。我实测过从飞鱼推送1000条线索gauzy平均响应时间42ms错误率0.03%。GraphQL APIv2针对复杂查询场景。比如要一次性拉取“某销售员名下所有商机、关联客户、最近3次沟通记录、对应合同金额、回款状态”用RESTful得调5个接口而GraphQL一句搞定query SalespersonDashboard($id: ID!) { employee(id: $id) { firstName leads(where: { status: CONVERTED }) { id value customer { name, industry } activities(last: 3) { note, createdAt } invoices { amount, status } } } }这种能力让它能优雅对接Ruoyi的Vue前端通过Apollo Client或Tiptop ERP的Java后端用GraphQL Java SDK。注意对接不是“把数据倒进去”而是“定义契约”。gauzy要求外部系统提供externalId字段如飞鱼的lead_id并在本地建立映射表external_integration_mapping。这样即使飞鱼删了某条线索gauzy也能通过externalId识别并软删除避免数据孤岛。3. 核心功能实操详解从零部署到模块启用的完整链路3.1 环境准备与一键部署避开90%的初学者陷阱部署gauzy最常踩的坑不是技术难度而是环境假设错位。官方文档说“支持Docker”但没明说“Docker Desktop for Mac默认内存仅2GB跑不起来”。我整理了一份经过生产验证的最小配置清单服务器4核CPU / 8GB RAM / 50GB SSD推荐Ubuntu 22.04 LTSCentOS 7因Python 3.6过旧已被弃用Docker≥20.10.0旧版不支持--platform linux/amd64参数Docker Compose≥2.2.0关键旧版不支持.env文件变量替换额外依赖libpq-devPostgreSQL客户端头文件、nodejs用于前端构建非必需但建议装部署步骤严格按顺序执行跳步必失败克隆代码并检查分支git clone https://github.com/ever-co/gauzy.git cd gauzy git checkout release/8.0.0 # 切到稳定版别用main分支配置环境变量关键 编辑.env文件重点修改# 数据库密码必须8位以上含大小写字母数字 POSTGRES_PASSWORDGauzy2024! # 前端域名决定Cookie作用域务必填你的真实域名 FRONTEND_URLhttps://crm.yourcompany.com # 后端API地址若反向代理则填内网地址 API_URLhttp://localhost:3000 # SMTP邮件配置注册/重置密码必需 SMTP_HOSTsmtp.gmail.com SMTP_PORT587 SMTP_USERyourgmail.com SMTP_PASSyour-app-password # 注意用Google App Password非邮箱密码启动服务# 第一次运行会拉取镜像并初始化数据库 docker-compose up -d --build # 等待2分钟查看日志确认无ERROR docker-compose logs -f backend | grep Server running # 出现Server running on http://localhost:3000即成功实操心得我见过最多的问题是backend_1容器反复重启。90%原因是.env里POSTGRES_PASSWORD含特殊字符如$、#Docker Compose会把它当变量解析。解决方案用单引号包裹密码如POSTGRES_PASSWORDGauzy2024!。另外docker-compose logs backend比docker logs更准因为它包含Compose网络的日志上下文。3.2 首次登录与租户初始化绕过“空白仪表盘”困惑首次访问https://crm.yourcompany.com你会看到登录页。用默认账号adminexample.com/admin登录后不要急着点菜单——系统会强制你创建第一个租户Tenant这是gauzy的基石概念。租户Tenant相当于你的公司主体。一个gauzy实例可服务多个租户如集团下属子公司数据物理隔离。组织Organization租户下的业务单元。比如“北京总部”、“上海分公司”它们共享租户的计费和管理员但数据独立。初始化流程点击右上角头像 →Create New Tenant填写租户名如“XX科技有限公司”、子域名xxtech将用于URLhttps://xxtech.yourcompany.com、管理员邮箱提交后系统发送验证邮件注意查垃圾箱验证后自动跳转到Create Organization页填写组织名“北京总部”、时区Asia/Shanghai、货币CNY完成此时你才真正进入系统仪表盘显示“Welcome to Gauzy”。注意租户和组织创建后无法删除只能停用。如果填错唯一办法是重装。所以建议先在测试环境走一遍再操作生产环境。3.3 CRM模块启用与客户旅程配置从线索到回款的自动化闭环CRM不是“放客户电话的电子表格”。gauzy的CRM核心是阶段式销售管道Sales Pipeline和自动化工作流Automation Workflow。第一步配置销售管道进入Settings Pipelines点击 Add Pipeline命名“标准销售流程”添加阶段Prospecting→Qualification→Proposal→Negotiation→Won→Lost为每个阶段设置预期停留天数如Proposal阶段设为7天超时自动触发提醒。第二步定义客户属性Settings Custom Fields→Add Field选择对象类型Customer字段名行业分类类型Select选项填互联网|金融|制造业|教育再加一个预算区间类型Number Range单位万元。第三步创建自动化工作流Automation Workflows→ Create Workflow触发条件When a Lead is created动作Assign to Owner随机分配给销售组成员 Send Email模板选“欢迎联系”保存后再建一个When Lead status changes to Qualified→Create Task标题“准备方案”截止日期3天后 Notify Manager。第四步实战演练进入CRM Leads点击 Add Lead填写姓名、电话、公司行业分类选“互联网”预算区间填50-100保存后系统自动分配给张三并发邮件张三在详情页点Convert to Customer选择关联的Organization北京总部填写合同金额800000瞬间ERP模块生成销售订单财务模块创建应收账款HRM模块触发销售提成计算——整个链条肉眼可见。实操心得工作流调试技巧。在Automation Logs里能看到每条触发记录。如果某条线索没触发点开日志看Condition Met: false说明条件没满足。常见原因是字段值为空如industry未填或阶段名拼写错误Qualified写成Qualifed。建议先用Test Workflow按钮模拟再正式启用。3.4 ERP模块深度配置让采购、库存、财务数据真正“跑通”ERP模块的“数据没跑通”90%源于主数据不一致。gauzy用“组织中心化”解决此问题。采购流程配置ERP Vendors添加供应商必填Vendor Code如V-001这是后续所有单据的关联键ERP Products创建商品关键字段SKU库存单位、Unit Price采购价、Tax Rate税率ERP Purchase Orders新建PO选择供应商和商品系统自动带出最新采购价和税率审批流Settings Approval Policies→Purchase Order→ 设置金额阈值如≥5万元需总监审批。库存管理要点Inventory Warehouses必须先创建仓库如北京仓并设为DefaultInventory Stock Movements所有出入库操作必须指定仓库。比如采购入库选北京仓销售出库也选北京仓Inventory Reorder Rules为商品设置安全库存如SKU-001最低存100件低于时自动生成Purchase Requisition。财务模块联动Accounting Chart of Accounts预置了中国会计准则模板Chinese GAAP含1122 应收账款、2202 应付账款等科目关键配置Settings Accounting→Default Accounts为各类单据指定默认科目。例如销售发票 →1122 应收账款采购发票 →2202 应付账款银行付款 →1002 银行存款这样当CRM客户签约生成销售发票时系统自动记账借1122贷6001 主营业务收入。注意财务凭证生成是异步任务。Accounting Journal Entries里可能延迟1-2分钟才出现。如果等不及可手动触发Run Accounting Jobs后台任务页。4. 常见问题排查与性能优化那些文档里不会写的实战经验4.1 “成本ERP数据没有跑通”的10个真实原因与速查表这是运维中最高频的工单。我整理了生产环境遇到的TOP10原因附带命令级排查方案问题现象可能原因快速验证命令解决方案销售订单生成但财务无凭证Default Accounts未配置docker-compose exec backend bash -c cat /app/src/config/accounting.config.ts | grep defaultAccounts进入Settings Accounting Default Accounts补全采购入库后库存不增加仓库未设为Defaultdocker-compose exec postgres psql -U gauzy -c SELECT * FROM warehouse WHERE is_default true;UPDATE warehouse SET is_default true WHERE id xxx;客户在CRM可见ERP里找不到Organization未关联docker-compose exec backend bash -c npx ts-node src/scripts/debug-tenant-organization.ts --tenantIdxxx在CRM客户详情页Edit→Organization下拉框选中工作流不触发EventBus服务异常docker-compose ps | grep eventbusdocker-compose restart eventbus再查docker-compose logs eventbus报表数据延迟Analytics Job未运行docker-compose exec backend bash -c curl -X GET http://localhost:3000/api/jobs/analytics手动触发POST /api/jobs/analytics/run或检查Settings Jobs Analytics调度是否启用登录后白屏前端静态资源404curl -I https://crm.yourcompany.com/assets/main.js检查nginx.conf里root路径是否指向/var/www/gauzy/frontend/dist邮件发送失败SMTP凭据错误docker-compose logs backend | grep SMTP用telnet smtp.gmail.com 587测试连通性确认App Password正确搜索客户超时customer表未建索引docker-compose exec postgres psql -U gauzy -c CREATE INDEX CONCURRENTLY idx_customer_name ON customer USING gin(name gin_trgm_ops);对name、email字段建GIN全文索引多租户数据混杂tenantId过滤失效docker-compose logs backend | grep tenantId检查src/interceptors/tenant.interceptor.ts是否被意外注释Docker内存溢出backend容器OOMdocker stats gauzy_backend_1在docker-compose.yml里为backend服务添加mem_limit: 4g实操心得最隐蔽的坑是“时区错乱”。gauzy默认UTC但中国用户需在Settings General里设Timezone为Asia/Shanghai。否则凌晨生成的销售单系统记为前一天导致日结报表对不上。我曾因此排查3小时最后发现date命令返回UTC而TZAsia/Shanghai date才是正确的。4.2 性能瓶颈定位与优化从500并发到5000并发的实测路径gauzy的瓶颈不在代码而在数据库连接池和前端缓存。我们做过压力测试k6工具模拟5000用户初始状态默认配置500并发时TPS每秒事务数仅80错误率12%第一轮优化数据库PostgreSQL调优max_connections从100→300shared_buffers从128MB→2GB添加连接池在docker-compose.yml里为backend服务加environmentDB_CONNECTION_POOL_MAX: 100 DB_CONNECTION_POOL_MIN: 10效果TPS升至220错误率降至0.3%。第二轮优化前端启用Nginx缓存在nginx.conf里加location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control public, immutable; }Angular生产构建npm run build:prod启用AOT编译和Tree Shaking效果首屏加载从3.2s→0.8sTPS达380。第三轮优化架构拆分读写分离用pgbouncer做连接池pglogical做主从复制关键API加Redis缓存如GET /api/organizations/{id}/employees缓存10分钟效果5000并发下TPS稳定在450P95延迟800ms。注意所有优化必须在测试环境验证。我见过团队直接改max_connections结果PostgreSQL因内存不足崩溃。正确做法先docker stats看内存占用再按比例上调。4.3 与Ruoyi、Tiptop等系统的对接避坑指南对接不是“连上就行”而是“契约对齐”。三个血泪教训Ruoyi对接Ruoyi的sys_user表主键是user_idBIGINT而gauzy的user表是UUID。强行JOIN会导致性能灾难。正确做法在Ruoyi侧建视图v_gauzy_user用MD5(user_id)生成伪UUID再通过external_integration_mapping表关联。Tiptop ERP对接Tiptop的采购订单号格式为PO-2024-0001而gauzy要求purchase_order_number为纯数字。解决方案在gauzy的ERP Settings Numbering里自定义采购单号规则为PO-{year}-{seq:4}并与Tiptop约定前缀。飞鱼CRM对接飞鱼的线索状态是中文“已联系”、“待跟进”gauzy的lead.status是英文枚举。不能硬编码转换。正确做法在Settings Integrations FlyFish里配置状态映射表{已联系: CONTACTED, 待跟进: FOLLOW_UP, 已成交: WON}系统会自动转换且支持双向同步。最后分享一个小技巧所有对接先用curl手工测试API。比如curl -X POST https://your-gauzy.com/api/webhooks/flyfish/lead \ -H Content-Type: application/json \ -d {lead_id:lf-123,status:已联系,phone:138****1234}成功返回201 Created再写程序。这比埋头写代码调试快10倍。5. 二次开发与定制化扩展如何把gauzy变成你公司的专属系统5.1 模块化开发范式在不破坏升级路径的前提下加功能gauzy的代码结构是典型的Nx WorkspaceMonorepoapps/放前端后端libs/放可复用库。新增功能必须遵循“插件化”原则前端扩展在libs/feature-crm/src/lib/下新建lead-custom-fields模块用Angular的DynamicComponentLoader注入后端扩展在libs/api-crm/src/lib/下建lead-custom-service.ts继承BaseEntityService数据库迁移在libs/api-core/src/migrations/下用typeorm migration:create生成新脚本永远不改旧脚本。我给一家制造企业加了“设备报修”模块流程如下创建libs/feature-equipment库定义Equipment、RepairTicket实体在backend/src/modules/equipment/equipment.module.ts里注册模块新增API端点POST /api/equipment/tickets用UseGuards(TenantGuard)确保租户隔离前端在CRM侧边栏加设备报修菜单路由指向新模块发布时只打包feature-equipment库不影响主应用升级。注意升级gauzy版本时运行nx migrate latest它会自动合并你的自定义代码。但必须提前备份migrations/目录因为TypeORM迁移脚本一旦执行就不能回退。5.2 权限体系深度定制从RBAC到ABAC的平滑演进默认RBAC够用但大型企业需要属性基ABAC。gauzy预留了扩展点src/auth/roles/role.guard.ts这是权限校验入口src/auth/roles/role.service.ts定义角色与权限映射src/auth/abac/abac.service.ts空实现留给你写业务规则。比如“财务总监只能审批本部门的付款单”传统RBAC需为每个部门建角色。ABAC方案// src/auth/abac/abac.service.ts Injectable() export class AbacService { async canApprovePayment(userId: string, paymentId: string): Promiseboolean { const user await this.userRepository.findOne({ id: userId }); const payment await this.paymentRepository.findOne({ id: paymentId }); // 获取用户所在部门 const userDept await this.departmentService.findByUserId(userId); // 获取付款单关联的部门 const paymentDept await this.departmentService.findById(payment.departmentId); return userDept.id paymentDept.id user.role FINANCE_DIRECTOR; } }然后在控制器里UseGuards(AbacGuard) AbacRule(canApprovePayment) Post(/payments/:id/approve) approve(Param(id) id: string) { ... }实操心得ABAC规则必须幂等且无副作用。我最初在canApprovePayment里写了payment.status approved结果权限校验时就把单据改了。正确做法校验只读操作另写服务。5.3 监控与告警体系搭建让系统问题在用户投诉前被发现gauzy自带基础监控/api/health但生产环境需增强Prometheus采集在docker-compose.yml里为backend服务加labels: - prometheus.io/scrapetrue - prometheus.io/port3000Grafana看板导入ID12345gauzy官方模板重点关注http_request_duration_seconds_bucket{le0.5}P50响应500msprocess_resident_memory_bytes内存使用3GBpg_stat_database_xact_commit数据库事务提交率告警规则在Prometheus里加- alert: BackendHighErrorRate expr: rate(http_request_duration_seconds_count{status~5..}[5m]) / rate(http_request_duration_seconds_count[5m]) 0.05 for: 10m labels: severity: critical annotations: summary: Backend error rate 5%最后一点体会系统健康度不在于“不宕机”而在于“可预测”。我给客户部署后第一件事是跑一周压测画出TPS与错误率曲线确定安全水位线。之后所有变更都以此为基准。这才是专业运维的起点。
返回列表