# buradmin **Repository Path**: pennyfine/buradmin ## Basic Information - **Project Name**: buradmin - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-13 - **Last Updated**: 2026-08-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Bun Admin Framework 基于 **Bun + Elysia** 后端与 **Vue3 + Element Plus(pure-admin-thin)** 前端的后台管理骨架。 ## 技术栈 | 端 | 技术 | | --- | --- | | 后端 | Bun、Elysia、Drizzle ORM、PostgreSQL、JWT | | 前端 | Vue3、Vite、Element Plus、Pinia、pure-admin-thin | ## 目录 ``` bun_framework/ server/ # Bun 中台 web/ # 中台管理端 station/ # Go 场站(设备接入 + 本机 UI) README.md ``` ## 环境准备 1. 安装 [Bun](https://bun.sh)(本机可用 `~/.bun/bin/bun`) 2. 安装 Node.js 20+ / 22+ 与 pnpm(前端) 3. 使用 ServBay 启动 PostgreSQL,并确保已有数据库 `bun_admin` 本地连接示例: ```env DATABASE_URL=postgres://uursel:ServBay.dev@127.0.0.1:5432/bun_admin ``` ## 启动后端 ```bash cd server cp .env.example .env # 按需修改 bun install # 首次建表(若尚未执行) psql "$DATABASE_URL" -f drizzle/0000_init.sql # 或:bun run db:migrate bun run db:seed bun run dev ``` - API: http://localhost:3000 - Swagger: http://localhost:3000/swagger 默认账号: - 用户名:`admin` - 密码:`admin123` ## 启动前端 ```bash cd web pnpm install pnpm dev ``` - 前端: http://localhost:8848 - 开发代理:`/api` → `http://127.0.0.1:3000` ## MVP 功能 - 登录 / 退出 / 当前用户 / refresh token - 用户管理 CRUD - 角色管理 CRUD + 菜单权限分配 - 菜单管理(树)+ 动态路由 - 接口权限码校验(如 `system:user:add`) ## 目录约定(server) ```text server/src/ sdk/ # 对外公共服务(插件/系统统一入口) core/ # 框架内核:config / db / plugins / services / utils system/ # 系统管理:auth / user / role / menu feature/ # 功能包注册、installed.json、菜单同步 features// # 可选功能包(如 upload) channels/app/ # App 端固定通道(鉴权);业务 API 由 features 自挂 /api/app/... channels/open/ # 无鉴权公开通道;业务公开 API 由 features 自挂 /api/open/... ``` ## 功能包(Features) 用户/角色/菜单在 **system**,不进功能包。可选业务放在 `features/`: - 启用清单:`server/src/system/feature/installed.json` 或 `ENABLED_FEATURES=upload`(环境变量优先;未设置时可在插件管理热切换) - catalog:启动扫描 `features/*/index.ts`(`feature.pack.json` 的 `server.entry` 给打包用,运行时仍扫 `index.ts`) - 核心菜单源文件:`server/src/system/menus.json`(`db:sync-features` / seed 同步) - 功能包菜单源文件:`features//menus.json`(`menus.ts` 导出) - `feature.pack.json`:`server.entry` / `web.entry` / `migrations` 是打包清单(相对本包目录;`web.entry` 相对 `web/src/features//`),`feature:pack` / `feature:install` 会读 - 回收站:系统管理 → **回收站**(用户/文件软删入站;彻底删除文件会删磁盘) - 日志审查:系统管理 → **日志审查**(按类型 auth/audit/error/feature/system 过滤;写入 `sys_log`) - 边界检查:`cd server && bun run lint:features` - 功能包配置描述:`features//config.schema.json`(挂到 `FeaturePack.configSchema`) - 运行时配置:存 `sys_config`,热读 Redis(`cfg:{namespace}`);密钥仍走 `.env` - Redis 热路径缓存:`auth:user:{id}`(鉴权用户状态)、`rbac:menus|roles:{id}`(配合 `rbac:ver`)、`upload:folders`(目录树) - 权限实时性:JWT 只证明身份,`permission` 宏每次读 RBAC 缓存/库 - 登录限流:同 IP+用户名 15 分钟 10 次;refresh 同 IP 15 分钟 60 次(Redis `rl:*`,不可用时内存降级) - 后台浏览:系统管理 → **Redis 缓存**(默认仅应用前缀,可查看/修改/删除 string key) - 后台管理:系统管理 → **插件管理** → 详情 → **配置 / 菜单设置**;系统级配置在 **系统配置** - CLI 同步:`cd server && bun run db:sync-features` - **系统 → 插件**:只 import `@/sdk`(`featureHost` / `adminPlugin` / `appPlugin`),不要直接打 `core/*` - 分页:`paginateFrom(db, table, { query, where, orderBy })` 或 `paginate({ query, count, list })`(`featureHost.http` / `@/sdk`) - **插件 → 插件**:只 import 对方 `public.ts` - 系统钩子:经 `featureHost.hooks`;当前 `app.start` / `app.stop`,功能包在 `FeaturePack.hooks` 声明 ### upload 能力包(默认启用) ``` server/src/features/upload/ index.ts / public.ts / feature.pack.json / config.schema.json / menus.json api/ # HTTP 路由、handlers db/schema.ts # 表定义 db/migrations/ # 插件自己的 SQL storage/ # 本地目录、媒体类型 web/src/features/upload/ api.ts / views/ / components/ ``` - 管理端菜单:资源管理 → 文件库 - 目录树、按图片/视频等筛选、预览、上传入库 - 业务插入:`openFileBrowser({ multiple, mediaType, scope: 'all'|'mine' })` - 回传带 `source: 'library' | 'upload'` ### iot 业务包 - 代码:`server/src/features/iot/`、`web/src/features/iot/` - **功能计划**:[`server/src/features/iot/PLAN.md`](server/src/features/iot/PLAN.md)(Bun 中台 + Go 场站) - 依赖能力包 **`site-sync`**(场站管理 + HMAC / Outbox):[`server/src/features/site-sync/`](server/src/features/site-sync/) · 契约 [`docs/central-site-auth.md`](server/src/features/site-sync/docs/central-site-auth.md) - 场站进程:[`station/`](station/)(双 SQLite、设备 WS、本机 Vue、`/ws/app` 经 frp) ### 打包到其它同构项目 ```bash # 在本仓库打包 bun run feature:pack upload # 安装到目标项目(需已具备 features 宿主;catalog 自动扫描) bun run feature:install dist/features/bun-admin-feature-upload-0.1.0.tgz --project /path/to/other cd /path/to/other/server && bun run db:sync-features # 新包代码需重启一次进程;之后可在插件管理热启用/停用 ``` ## 通道(Channels) | 通道 | 前缀 | 鉴权 | 用途 | |---|---|---|---| | `open` | `/api/open/*` | 无 | 公开资源(健康检查、落地页配置、公开文件等);WS:`/api/open/ws` | | `app` | `/api/app/*` | `appPlugin`(`app_user`) | C 端业务;WS:`/api/app/ws?token=` | | 管理端 | `/api/*`(system) | `adminPlugin`(`sys_user` + RBAC) | 后台 | 业务公开/App 接口由各 `features/` 自行挂到对应前缀,不要堆进 `channels/`。 单实例 WS 连接表:`wsHub`(`@/sdk` / `featureHost.ws`)。插件推送示例:`wsHub.sendToUser("app", userId, { type: "notify", ... })`。 ### Open 通道 - `GET /api/open/health` 公开健康检查 - `GET /api/open/ping` 公开 ping - `WS /api/open/ws` 公开 WebSocket(发 `{ "type": "ping" }` 回 pong) ### App 通道 固定通道在 `channels/app/`(鉴权与约定)。路径前缀:`/api/app/*`(与管理端隔离)。 - 身份域:`app_user`(普通用户),与后台 `sys_user` 分离;token 带 `typ=app`,`sub` = `app_user.id` - Token 默认更长:access `APP_JWT_EXPIRES_IN=7d`,refresh `APP_JWT_REFRESH_EXPIRES_IN=30d`(管理端仍为 2h / 7d) - 可选关联:`app_user.sys_user_id`(同一人既是员工又是 App 用户) - `POST /api/app/auth/login` App 登录(返回 access + refresh) - `POST /api/app/auth/refresh` 刷新令牌 - `POST /api/app/auth/logout` 作废 refresh - `GET /api/app/auth/profile` 当前用户资料(需 Bearer) - `WS /api/app/ws?token=` App WebSocket(也可用升级请求 `Authorization: Bearer`) - 业务接口由各 `features/` 自行挂到 `/api/app/...`,用 `appPlugin`(`@/sdk`) - 默认种子账号:`demo / demo123` ## 常用脚本 ### server - `bun run dev` 开发监听 - `bun run db:seed` 种子数据 - `bun run db:migrate` 执行 drizzle 迁移 - `bun run db:sync-features` 同步功能包菜单 ### 根目录 - `bun run feature:pack ` - `bun run feature:install ` - `bun run feature:uninstall ` ### web - `pnpm dev` 开发 - `pnpm build` 构建