从 0 到 1 搭建 AI 驱动的日志管理系统:Vue3 + Express + PostgreSQL 全栈实践
前言
团队工作日志管理是个老问题:现有工具要么太重(动辄上百个功能),要么太轻(就是个文本框)。我想要的是一个聚焦日志场景、AI 深度集成、权限精细可控的系统。于是有了这个开源项目。
本文记录从技术选型到核心实现的完整过程,希望对你做类似系统有参考价值。
源码:github.com/smarkfire/P… (求 Star ⭐) 在线 Demo:pm-tools-log.vercel.app
技术选型
| 层级 | 选型 | 理由 |
|---|---|---|
| 前端 | Vue 3 + TypeScript + Vite + Element Plus | 组合式 API 写起来顺手,Element Plus 表单/表格组件齐全 |
| 后端 | Node.js + Express + TypeScript | 前后端同语言,AI 接口调用用 fetch 很方便 |
| 数据库 | PostgreSQL 16 | JSON 字段、CTE、窗口函数都很顺手 |
| AI | 通义千问 / DeepSeek | 都提供 OpenAI 兼容接口,一套代码切换供应商 |
核心架构设计
1. 双层角色权限模型
这是整个系统最核心的设计。我把角色拆成两层:
全局角色(users.role) 项目角色(project_members.project_role)
───────────────────── ──────────────────────────────────────
director 项目总监 manager 项目经理
member 普通用户 leader 小组长
member 组员
数据范围计算逻辑:
- 总监:所有数据
- 其他人:遍历
project_members表,汇总该用户在各项目中的角色范围,取并集
-- 某用户能看到的日志 user_id 列表(伪代码)
SELECT DISTINCT user_id FROM work_logs
WHERE user_id = :me
OR project_id IN (
-- 我是经理的项目
SELECT project_id FROM project_members WHERE user_id = :me AND project_role = 'manager'
)
OR (project_id, user_id) IN (
-- 我是组长的小组内的成员
SELECT pm.project_id, pm2.user_id
FROM project_members pm
JOIN project_members pm2 ON pm2.group_id = pm.group_id
WHERE pm.user_id = :me AND pm.project_role = 'leader'
)
这个设计的好处是:一个人可以在 A 项目当经理、在 B 项目当组员,数据范围自动正确。
2. AI 集成的三级 Key 优先级
用户配置 Key(user_ai_config 表)
↓ 没有则用
系统配置 Key(system_config 表,管理员界面维护)
↓ 没有则用
服务器 .env 兜底
这样既支持"每个人用自己的 Key",也支持"团队统一配一个 Key",管理员还能通过菜单开关决定是否允许用户自己配置。
3. AI 对话的权限边界
AI 对话不是无限制的。系统会先按上面的权限模型计算出当前用户能看到的日志范围,再把这些日志作为上下文喂给 AI。组员问"上周项目整体进展",AI 只能基于他自己的日志回答,不会越权。
4. 数据库幂等初始化
所有建表和种子数据都写在 initDb.ts 里,用 CREATE TABLE IF NOT EXISTS + INSERT ... WHERE NOT EXISTS 保证可重复执行。首次初始化还会插入 8 个演示账号和近两周的演示日志,部署完就能直接体验。
踩过的坑
坑 1:Supabase 直连地址在 Vercel 上连不通
Supabase 的 db.xxx.supabase.co 只支持 IPv6,而 Vercel Serverless Function 只支持 IPv4 出站。解决:用 Supabase 的 Pooler 连接池地址(aws-0-xxx.pooler.supabase.com),自动走 IPv4。
坑 2:.gitignore 的 logs/ 把源码目录也忽略了
.gitignore 里写了 logs/ 想忽略日志文件,结果把 web/src/views/logs/ 源码目录也排除了。本地 vercel deploy 正常(传本地文件),但 GitHub 自动构建时缺文件直接失败。解决:改成 /logs/ 锚定根目录。
坑 3:Serverless 环境下数据库连接池要缩小
Vercel 函数是冷启动 + 短生命周期,连接池 max 要从 20 降到 3,idleTimeoutMillis 从 30s 降到 10s,否则容易耗尽连接。
部署
一行命令部署到 Vercel,数据库用 Supabase:
# 配置环境变量
DATABASE_URL=postgresql://...pooler.supabase.com:5432/postgres
JWT_SECRET=your-secret
SETUP_KEY=your-setup-key
# 推送即自动部署(已连接 GitHub)
git push origin main
构建脚本会自动执行:前端构建 → 数据库幂等初始化 → 线上冒烟测试。
总结
这个系统的核心价值在于三个设计决策:
- 双层角色模型——灵活且严谨的数据权限
- 三级 AI Key 优先级——兼顾个人与团队场景
- AI 对话的权限边界——不越权、不漏权
完整代码已开源,求 Star ⭐ 支持:
8 个演示账号(密码 123456)可直接体验:pm-tools-log.vercel.app