Files
mce/docs/structure.md
Victor_Jay c3dec09dae feat(settings): 个人资料编辑 + 头像上传/裁切 + 自定义裁切弹窗
**新增功能:**

用户名编辑:输入框替换静态文本,白名单验证(中文/英文/数字/下划线/连字符),前端计数器(n/16),utf8对齐PG VARCHAR,XSS防控。

个性签名编辑:Textarea,128字符上限,实时计数器。

头像上传管线:校验→解码→裁切→CatmullRom缩放→WebP二分编码≤100KB→原子写入(.tmp→os.Rename)。限制5MB,128-3840px,JPEG/PNG/WebP。输出512x512 WebP。文件名 {uid}_{timestamp}.webp。清理旧头像。

自定义裁切弹窗:浅色主题,固定裁切框+图片平移/缩放(1×-3×滚轮),box-shadow遮罩,三等分网格。坐标映射pan/zoom→原图像素→subImage。

CSP修复:img-src允许data:URI(FileReader预览)。

**文件变更:**
修改: README, docs/{development,structure}.md, go.{mod,sum}, cmd/server/main.go, controller/settings, middleware/security, router, templates/settings/{index.html,css}
新增: internal/service/avatar_service.go, docs/settings.md
2026-05-27 01:03:16 +08:00

136 lines
5.5 KiB
Markdown
Raw Permalink 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.

# 目录结构与分层规范
## 总览
```
METAZONE.FAN/
├── cmd/server/main.go # 入口:初始化→启动,只做编排,不写业务
├── internal/ # 内部包(不可外部 import
│ ├── config/ # 配置加载(结构体 + yaml/file
│ ├── router/ # 路由注册(按路由组拆文件)
│ ├── controller/ # 控制器(瘦)— 接参数 → 调服务 → 返回
│ │ ├── interfaces.go # 控制器层接口定义ISP
│ │ └── admin/ # 后台子包(功能多,独立拆)
│ ├── service/ # 业务逻辑(厚)— 核心逻辑、校验、编排
│ │ ├── repository.go # Service 层仓储接口定义ISP
│ │ └── avatar_service.go # 头像上传处理管线
│ ├── repository/ # 数据访问DAO— 纯数据库操作
│ ├── model/ # 数据模型 — 纯结构体 + DTO
│ ├── middleware/ # 中间件 — 每个中间件一个文件
│ ├── theme/ # 模板/主题管理 — 加载、切换、静态资源
│ └── common/ # 公共工具 — 响应格式、分页、校验、错误码
├── templates/ # 前端模板 — 多主题支持
│ ├── MetaLab-2026/ # 当前主题
│ │ ├── theme.json # 主题元信息
│ │ ├── guidelines.html # 准则等长文本(非模板,纯内容文件)
│ │ ├── html/ # 页面模板
│ │ │ ├── layout/ # 布局组件header/nav/footer
│ │ │ ├── home/ post/ comment/ user/ topic/ settings/
│ │ │ └── partials/ # 可复用组件(卡片/分页/侧栏)
│ │ └── static/ # 静态资源css/js/img
│ │ ├── css/
│ │ │ ├── common.css # 全局样式 + 导航
│ │ │ ├── home.css auth.css settings.css
│ │ └── js/
│ ├── MetaLab-2027/ # 未来主题(相同结构)
│ └── system/ # 系统模板email 等,与主题无关)
├── storage/ # 运行时数据(.gitignore
│ ├── uploads/avatars/ # 用户头像WebP
│ └── logs/
└── docs/ # 项目文档
```
## 各层职责与边界
### Controller控制器
- **只做三件事**:绑定请求参数 → 调用 Service → 返回响应
- 不允许直接调用 Repository
- 不允许写 if-else 业务分支逻辑
- 单文件 ≤ 120 行
- 每个领域实体一个文件,后台独立 `admin/` 子包
```go
// ✅ 正确:瘦控制器
func (c *PostController) Detail(ctx *gin.Context) {
id := ctx.Param("id")
post, err := c.postService.GetDetail(ctx, id)
if err != nil {
common.Error(ctx, common.ErrNotFound, "帖子不存在")
return
}
common.Ok(ctx, post)
}
```
### Service业务逻辑
- **承载所有业务规则**:权限校验、数据组装、事务编排
- 可以调用多个 Repository
- 单文件 ≤ 300 行
- 方法命名语义化:`Create`/`Update`/`Delete`/`GetDetail`/`ListByTopic`
### Repository数据访问
- **纯数据库操作**:增删改查,不含业务逻辑
- 单文件 ≤ 200 行
- 不引用 Controller 或 Service 层
### Model模型
- 纯结构体定义 + DTO
- 单文件 ≤ 80 行
- `common.go` 放 BaseModelID/CreatedAt/UpdatedAt
- `dto.go` 放请求/响应传输对象
### Middleware中间件
- 每个中间件一个文件,≤ 60 行
- 按关注点注册到路由组上,不要逐个路由单独加
### Router路由
- 按路由组拆文件:`web.go`(页面)、`api.go`API`admin.go`(后台)
- 只做路由映射,不写 handler 逻辑
### Theme主题管理
- `loader.go`:模板文件加载、内容文件读取
- `manager.go`:主题扫描、切换、获取当前
- `resolver.go`:静态资源路径解析(`/static/` → 当前主题 static 目录)
- `theme.go`:主题接口定义 + ThemeMeta 结构体
### Common公共工具
- `response.go`:统一 JSON 响应格式
- `error_code.go`:错误码常量
- `validator.go`:参数校验
- `pagination.go`:分页工具
## import 规则
```
允许的依赖方向(从上到下,不可反向):
controller → service → repository → model
controller → common
service → common + repository + model
middleware → common + service可选
router → controller + middleware
theme → 无(独立工具包)
```
- Controller **不可** import Repository
- Controller **不可** import 另一个 Controller
- Service **不可** import Controller
- Repository **不可** import Service
## 模板目录规范
- 每个主题 `templates/{主题名}/` 下有独立完整的 `html/``static/`
- 主题之间互不引用、互不依赖
- 长文本内容(准则、关于页面等)放主题根目录(`guidelines.html`),不在 `html/`
- 这些内容文件**不是模板**(不含 `{{}}` 语法),由 Controller 读取后注入
- 系统级模板email 等)放 `templates/system/`,与主题无关
- 切换主题时Gin 引擎重新指向新主题的 `html/` 目录