Files
easygoadmin-wiki/EasyGoAdmin_GoFrame_EleVue/zh/directory.md
T
2026-10-20 21:19:44 +08:00

136 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 1.3 项目目录结构
:::tip 概述
在软件开发过程中,优秀的目录结构对项目的组织、开发、维护和扩展至关重要。本项目后端采用"单包平铺"结构(api/controller/logic/service 各一个包,每模块一个文件),与常见的"按域分目录"不同——这是刻意的设计决策,详见下方说明。
:::
## 设计原则
```text
1. 目录平铺:api/v1、controller、logic、service 均为单包,每模块一个 snake_case 文件;
跨模块直接同包调用(如 user 直接调用 ResolveCityNames,无需 import)。
2. 分层架构:controller(HTTP)→ service 接口(依赖倒置)→ logic(业务)→ dao(数据),职责清晰。
3. 模块化管理:25 张表对应 27 个模块文件,文件名 = 表名去 goframe_ 前缀。
4. 依赖红线:中间件不依赖业务层(函数变量接线)、task 单向依赖 logic、migrate 不走 dao。
```
## 项目根目录
```text
├── main.go # 服务入口:注册五库驱动 + Redis 适配器 → cmd.Run
├── Makefile # run/build/test/vet/fmt/gen(gen-dao)/clean
├── api/ # 全部请求/响应结构体(单包 v1)
│ └── v1/ # 每模块一文件:user.go、config_item.go…
├── cmd/ # CLI 入口
│ ├── generator/ # 代码生成器 CLI(go run ./cmd/generator)
│ └── migrator/ # 整库迁移 CLI(go run ./cmd/migrator)
├── internal/ # 后端核心代码(详见下方)
├── templates/ # 代码生成器模板(后端 {{ }} 定界;ui* 前端 [[ ]] 定界)
│ └── ui/ ui2/ # 前端模板(ui2 为树形模块变体)
├── utility/ # 基础能力包(无业务依赖)
├── manifest/
│ ├── config/config.yaml # 运行时配置(唯一配置文件)
│ └── data/ip2region.xdb # IP 归属地库
├── resource/
│ ├── static/ # 静态资源(验证码字体等)
│ ├── swagger/ # 本地托管 API 文档页面
│ └── upload/ # 上传文件静态服务根(SetServerRoot "resource")
├── hack/ # gf gen dao 配置与自定义模板、黄金样本回归基线
├── .dockerignore # Docker 构建上下文排除清单(硬规则:必须在上下文根目录)
├── docker/ # Docker 化文件(构建上下文为项目根,-f docker/Dockerfile)
│ ├── Dockerfile # 多阶段构建:静态编译 → alpine 运行(非 root + HEALTHCHECK)
│ ├── docker-compose.yml # 三服务编排:后端 + MySQL8 + Redis7(GF_ 注入配置)
│ └── .env.example # compose 变量模板(复制为 .env,明文密钥不入库)
├── ui/ # 前端工程(Vue3 + Element Plus)
├── document/ # 项目文档(五方言 SQL 脚本、架构定稿、wiki 等)
│ ├── mysql/ # MySQL 定稿 DDL(规范基准)
│ ├── postgresql/ # PostgreSQL 定稿 DDL
│ ├── sqlserver/ # SQL Server 定稿 DDL
│ ├── oracle/ # Oracle 定稿 DDL
│ ├── sqlite/ # SQLite 定稿 DDL
│ ├── architecture.md # 架构定稿
│ └── wiki/ # 后端开发者文档
├── upload/ # 上传物理目录(file.uploadDir)
├── log/ # 运行日志
└── bin/ # 编译产物
```
## 后端目录(internal/)
```text
internal/
├── cmd/ # 启动编排:cache.Init → 依赖接线 → 路由 → 调度器 → 运行
├── consts/ # 业务错误码 / 缓存键 / 上下文键 / 日志类型枚举
│ ├── biz_err.go # 17 个业务错误码(gcode.Register 语义值)
│ ├── cache_key.go # Redis 键统一前缀 easygoadmin:
│ ├── context_key.go # 上下文读写(consts.GetXxx(ctx))
│ └── log_type.go # 41 个操作日志类型常量与静态映射
├── controller/ # 控制器(单包,薄层,仅转发 service)
│ ├── user.go # CUser:Page/List/Detail/Add/Update/Status/…
│ └── … # 文件命名 snake_case 对齐 dao
├── dao/ # 数据访问层(自定义模板产出,挂钩子 + Ctx 覆写)
│ └── internal/ # dao 内部实现(自动生成,勿手改)
├── logic/ # 业务逻辑(单包,每模块一文件,同包 init 注册)
│ ├── base.go # 共享能力层(文件/富文本/字典/事务/分块/树,15 个导出上限)
│ ├── module_spec.go # ModuleSpec 泛型声明式 CRUD 基座
│ ├── data_scope.go # 行级数据权限共享工厂 ApplyDataScope
│ ├── user.go role.go … # 各模块业务实现(sUser/sRole…)
│ └── generator_side.go # 生成器副作用(菜单/字典/路由注册)
├── middleware/ # 7 个中间件 + 白名单 + 依赖接线(wire.go)
│ ├── cors.go response.go # CORS / 响应兜底(SVG 加固、panic 恢复)
│ ├── ratelimit.go demo.go # 限流 / 演示模式
│ ├── jwt.go tenant.go # 认证 / 租户状态校验
│ ├── operation_log.go # 操作日志异步采集
│ ├── public.go # 免登录白名单(精确匹配)
│ └── wire.go # IdentityLoader/TenantLoader/LogSink 函数变量
├── migrate/ # 整库迁移引擎(内省/翻译/DDL 渲染/搬运/序列修复)
├── model/
│ ├── entity/ # 实体(gf gen dao 产物)
│ ├── do/ # 数据对象 DO(gf gen dao 产物)
│ └── hooks/ # 全局模型钩子(审计盖章/软删改写/租户隔离)
├── router/ # 路由注册(router.go)+ gmeta 反射绑定(bind.go)
│ └── meta/ # 路由元数据表(权限/日志注解即事实)
├── service/ # 服务接口层(每模块一文件,手维护,勿运行 gf gen service)
└── task/ # 定时任务处理器(init 自注册到 logic.RegisterJobHandler)
├── task.go # 注册与参数辅助
├── hello_world.go # 示例任务(验证调度链路)
├── send_sms.go # 短信示例任务
└── log_clean.go # 日志清理内置任务(每日 02:30)
```
## 前端目录(ui/src/)
```text
ui/src/
├── api/ # 接口模块(按域分目录:system/data/content/monitor/tool…)
├── components/ # 公共组件(25 类:Table/Form/Upload/Editor/Excel/ChinaArea…)
├── directives/ # 自定义指令(permission 权限指令等)
├── enums/ # 枚举常量(http/cache/page/permissions/role…)
├── hooks/ # 组合式函数(core/event/setting/web…)
├── layout/ # 布局系统
├── router/ # 路由(constant 常量路由 + generator-routers 动态菜单路由)
├── settings/ # 全局设置(项目设置/设计设置/组件设置/动画设置)
├── store/ # Pinia(modules:user/asyncRoute/tabsView/designSetting…)
├── styles/ # 全局样式与主题变量
├── utils/ # 工具库(http 请求封装/auth/storage/downloadFile…)
└── views/ # 页面(按域分目录)
├── system/ # user/role/menu/dept/level/position/tenant/logger
├── data/ # city/config/dict/notice/param
├── content/ # article/category/link
├── monitor/ # online/server/cache/job
├── tool/ # generator/example
├── file/ setting/ dashboard/ login/ exception/ iframe/ redirect/ about/
```
## 为什么选择"单包平铺"而非"按域分目录"
| 对比项 | 单包平铺(本项目) | 按域分目录 |
|--------|------------------|-----------|
| 跨模块复用 | 同包直接调用包级函数,零 import | 需要 import,易产生循环依赖 |
| 新增模块 | 4 个文件各放一处,位置固定无歧义 | 需要在多级目录间跳转 |
| 生成器产出 | 目标路径唯一确定 | 需推断目录层级 |
| 包体积 | 单包文件多,但 Go 编译无压力 | 包粒度细 |
| init 注册 | 同包全量加载,无需 blank import | 需要 blank import 触发 |
文件命名统一为表名去 `goframe_` 前缀的 snake_case(如 `config_item.go`、`file_template.go`),与 dao 产物命名对齐;前端文件仍使用驼峰(如 `fileTemplate.ts`)。