如何使用Golang开发小型CRM系统_Golang客户关系管理系统实战

9次阅读

go 写小型 CRM 完全可行,关键在快速收敛复杂度:用 sqlc 生成类型安全数据层、chi 构建分层中间件、embed+html/template 托管前端、Mailjet SDK 异步发信,并优先实现 MVP 功能。

如何使用Golang开发小型CRM系统_Golang客户关系管理系统实战

用 Go 写小型 CRM 完全可行,但别指望靠 net/http + 手写 SQL 就能撑住半年——核心在于快速收敛复杂度,而不是功能。

sqlc 代替手写 SQL 和 ORM

Go 生态里硬写 CRUD 最容易失控的环节就是数据层:自己拼 SQL、自己写 Struct 映射、自己处理 Nullable 字段、自己补事务逻辑。结果是 200 行 handler 里混着 80 行 db.QueryRowScan 调用。

  • sqlc 只要一个 query.sql 文件(比如 select * FROM customers WHERE id = $1),就能生成类型安全的 Go 函数,比如 GetCustomer(ctx, id),返回 Customer 结构体,字段名、类型、空值处理全由 SQL 注释或 schema 推导
  • 不引入运行时反射,没魔法,ide 跳转/补全正常;比 gorm 省掉 70% 的调试时间
  • 注意:sqlc 不生成 migration,DDL 还得靠 goosegolang-migrate 管理,SQL 文件和 migration 要人工对齐

路由和中间件别碰 gorilla/mux,直接上 chi

小型 CRM 需要带 auth、日志、panic 捕获、路径参数解析——但又不需要 kubernetes 级别的路由能力。此时 gorilla/mux 的 API 设计太松散,容易写出难以测试的闭包链;而 chi 的中间件是函数式组合,天然适合分层切关注点。

  • 比如登录校验中间件:func AuthMiddleware(next http.Handler) http.Handler,内部用 http.Request.Context() 存用户 ID,下游 handler 直接取 ctx.Value("user_id")
  • chi 支持 Route 分组,CRM 的 /api/customers、/api/contacts、/api/tasks 可以各自挂独立中间件,互不污染
  • 避免在中间件里做重定向或写响应体——只做鉴权、注入、记录,把“写 response”这件事严格留给 endpoint handler

embed 静态资源 + html/template 足够应付管理后台首页

小型 CRM 不需要 React/Vite 构建流程。Go 1.16+ 的 embed 能把 ./ui/dist 整个目录编译进二进制,配合 html/template 做简单变量替换(如当前用户姓名、未读消息数),页面加载快、部署就一个文件。

立即学习go语言免费学习笔记(深入)”;

  • 静态资源走 http.FileServer(http.FS(assets)),其中 assetsembed.FS 实例,不用单独起 nginx
  • 模板里别写复杂逻辑:{{if .IsAdmin}}...{{end}} 可以,但不要在 .html 里调用 formatDate 这类函数——提前在 handler 里算好字符串传进去
  • 如果后期要加图表,直接用 ,别把前端依赖打进 Go 编译过程

发邮件别自己连 SMTP,用 mailjetsendgrid SDK

本地测 SMTP 很容易卡在 DNS、TLS 握手、认证失败上;自己实现重试、退信解析、模板渲染,投入产出比极低。CRM 的客户通知、密码重置、任务提醒,本质是「触发式事件」,不是「实时通信」。

  • 用官方 SDK(如 mailjet/mailjet-apiv3-go)发邮件,3 行代码搞定:构造 Info{From, To, Subject, HTMLPart} → 调 SendMail → 检查 Response.StatusCode == 200
  • 关键动作(如创建客户、分配销售)后,启动 goroutine 异步发信,别阻塞主流程;失败日志打清楚,方便人工补发
  • 别在代码里硬编码邮箱密码——从环境变量读 MAILJET_API_KEYMAILJET_API_SECRET,本地用 .env,生产走 Secret Manager

真正卡住进度的从来不是“怎么写”,而是“哪些东西必须现在做,哪些可以三个月后再补”。比如搜索客户用 WHERE name ILIKE '%?%' 起步没问题,等客户量过万再切 elasticsearch;比如权限先按角色(admin/sales/support)粗粒度控制,别一上来就搞 RBAC 表设计。

text=ZqhQzanResources