73 lines
2.7 KiB
Markdown
73 lines
2.7 KiB
Markdown
# 4.6 目录结构设计
|
||
|
||
:::tip 概述
|
||
目录即架构:internal 对外不可见、utility 无业务语义、一模块四文件同名成套。本页解释"为什么这样分",目录树本身见 [1.3 项目目录结构](/zh/directory.html)。
|
||
:::
|
||
|
||
## 顶层划分的逻辑
|
||
|
||
| 目录 | 定位 | 判定标准 |
|
||
|---|---|---|
|
||
| internal/ | 业务代码 | 含业务语义,Go 编译器层面禁止外部引用 |
|
||
| utility/ | 基础设施 | 无业务语义,任何项目可复用 |
|
||
| cmd/ | 可执行入口 | package main,只做装配不做逻辑 |
|
||
| templates/ | 生成器模板 | 渲染产物是代码,非运行时依赖 |
|
||
| config/ resource/ | 运行期数据 | 配置与静态资源 |
|
||
| deploy/ | 交付物料 | Docker/Nginx,不参与编译 |
|
||
| document/ | 项目文档 | 规约与 SQL 脚本 |
|
||
| ui/ | 前端 | 独立工具链,独立生命周期 |
|
||
|
||
## internal 内部的分层逻辑
|
||
|
||
```text
|
||
model/ 数据形态的定义(dto 契约、db 连接、hooks 红线)
|
||
router/ HTTP 装配(注册引擎 + 元数据)
|
||
middleware/ 横切(每个文件一个关注点)
|
||
handler/ 入口(最薄)
|
||
service/ 业务(最厚)
|
||
repository/ 数据访问(唯一 SQL 触点)
|
||
task/ 后台(与请求链无关的定时逻辑)
|
||
server/ 生命周期(启动与关闭)
|
||
consts/ 跨层共享的常量
|
||
migrate/ 独立工具引擎(跨库迁移)
|
||
```
|
||
|
||
依赖只能向下:repository 不 import service,service 不 import handler。
|
||
|
||
## 一模块四文件的价值
|
||
|
||
同名的 `internal/{model/dto,repository,service,handler}/{module}.go`:
|
||
|
||
- **可检索**:`example` 一个关键词命中全链路
|
||
- **可生成**:生成器按同名规则产出与覆盖
|
||
- **可审查**:PR 按模块聚合,四文件即一个完整变更单元
|
||
- **规约自明**:新模块不问即知放哪里
|
||
|
||
## utility 的边界
|
||
|
||
utility 包禁止 import internal(基础设施不依赖业务)。内部互相引用仅限极底层(如 logger 被各包使用)。每个包一个关注点,13 个包与 config.yaml 配置节大体一一对应。
|
||
|
||
## 运行期目录
|
||
|
||
| 目录 | 内容 | 处置 |
|
||
|---|---|---|
|
||
| log/ | zap 文件日志 | LogClean 任务按保留期清理 |
|
||
| upload/ | 上传文件(temp + 正式子目录) | temp 按天清理;生产由 nginx 直供 |
|
||
|
||
两者都在 .gitignore,不进版本库。
|
||
|
||
## 前后端的对称性
|
||
|
||
```text
|
||
后端 RouteSpec Path: /api/example/page
|
||
前端 api 模块: ui/src/api/tool/example.ts → url: '/example/page'
|
||
后端菜单 component: tool/example/index
|
||
前端页面: ui/src/views/tool/example/index.vue
|
||
```
|
||
|
||
五处路径同构——这是生成器能一键打通前后端的原因。
|
||
|
||
## 下一步
|
||
|
||
→ [4.7 基座与公共体系](/zh/architecture/base-system.html)
|