84 lines
4.0 KiB
Markdown
84 lines
4.0 KiB
Markdown
# 4.5 目录结构设计
|
||
|
||
:::tip 概述
|
||
目录结构是架构决策的物理体现。本节解释"为什么这样放"——平铺单包、snake_case 命名、internal 边界、utility 无业务依赖等约定背后的原因。完整目录树见 [1.3 项目目录结构](../directory)。
|
||
:::
|
||
|
||
## 后端顶层布局与设计意图
|
||
|
||
```text
|
||
main.go 入口极薄:注册五库驱动 + Redis 适配器 → cmd.Run
|
||
internal/ 私有包边界(Go internal 语义:外部不可 import)
|
||
cmd/ 启动编排独立成包——把 main 的"做事"与"声明"分离
|
||
api/v1/ 契约层放 internal 外?——不,本项目放顶层 api/,
|
||
便于生成器与 gf 工具链定位,也表达"对外契约"语义
|
||
controller/ logic/ service/ dao/ 四层各自单包平铺
|
||
middleware/ 中间件 + wire.go 函数变量接线(不 import 业务包)
|
||
migrate/ 迁移引擎独立——gdb 裸连,必须与 dao 体系隔离
|
||
model/hooks/ 全局钩子独立于 entity/do(生成物与手写物分离)
|
||
router/ router.go(注册)+ bind.go(反射)+ meta/(元数据表)
|
||
task/ 定时任务实现——单向依赖 logic,cmd 空白导入触发
|
||
templates/ 生成器模板独立于 internal(模板演进与代码解耦)
|
||
utility/ 基础能力包——无业务依赖,可供任何层使用
|
||
manifest/ 配置与数据(ip2region.xdb)
|
||
resource/ 静态资源(SetServerRoot 提供 /upload/**、swagger 页面)
|
||
hack/ 工具链配置(gf gen dao 模板、golden 回归基线)
|
||
```
|
||
|
||
## 平铺 vs 分目录的取舍
|
||
|
||
| 维度 | 单包平铺(选择) | 按域分目录(弃用) |
|
||
|------|----------------|------------------|
|
||
| 跨模块复用 | 同包直接调用包级函数,零 import、无循环依赖风险 | 需 import,深组合易循环 |
|
||
| 新增模块 | 4 个文件各就各位,无目录推断 | 多级目录间跳转 |
|
||
| 生成器 | 目标路径唯一确定 | 需推断层级 |
|
||
| init 注册 | 同包全量加载,无需 blank import | 每包需 blank import |
|
||
| 代价 | 单包文件多(30+) | 包粒度细 |
|
||
|
||
Go 编译器对大包无压力,而"跨模块直接调用"的收益在中后台系统里极高(city 编解码、身份加载、字典文本被大量模块复用)。
|
||
|
||
## 文件命名规范
|
||
|
||
```text
|
||
后端(对齐 dao 产物):表名去 goframe_ 前缀的 snake_case
|
||
api/v1/config_item.go · internal/controller/config_item.go
|
||
internal/logic/config_item.go · internal/service/config_item.go
|
||
|
||
前端:驼峰
|
||
src/api/data/config.ts · src/views/data/configItem/
|
||
|
||
原因:后端文件名与 dao/entity/do 生成物一致,生成器与人工开发心智统一;
|
||
前端沿用 JS 社区驼峰惯例,两边各自从俗。
|
||
```
|
||
|
||
## internal 的边界价值
|
||
|
||
`internal/` 是 Go 编译器强制的私有边界——仓库外代码无法 import,防止外部项目把实现细节当公共 API 依赖。分层红线(controller 不 import dao 等)靠 code review + 生成器模板保证,internal 防的是"仓库外扩散"。
|
||
|
||
## utility 的纪律
|
||
|
||
```text
|
||
utility/* 只依赖标准库与三方库,禁止 import internal(防反向耦合)
|
||
|
||
cache 统一缓存门面(Redis 优先、内存降级)
|
||
captcha 验证码生成/校验
|
||
crypto bcrypt + salt
|
||
excel excelize 封装(ReadSheet/WriteSheet)
|
||
ip2region xdb 归属地(懒加载 + 读锁)
|
||
jwt HS256 双令牌 Sign/Parse
|
||
response 统一信封写出
|
||
ua OS/Browser 解析
|
||
upload 两段式上传(SaveTemp/SaveFromTemp/GetFileUrl)
|
||
```
|
||
|
||
## 前端目录设计
|
||
|
||
```text
|
||
views 按"域"分目录(system/data/content/monitor/tool…)与后端模块域对应;
|
||
api 同样按域分目录;
|
||
components/store/utils/hooks 不按域——全局共享层;
|
||
settings/styles/enums 全局配置面。
|
||
```
|
||
|
||
views 域归属与生成器 genDomainMap 一致(user/role→system,config→data,article→content,operation_log→monitor,example→tool,默认 tool),生成器据此决定前端产出路径。
|