签入版本

This commit is contained in:
小蚂蚁云
2026-10-20 21:53:26 +08:00
parent 5cc3da657c
commit b33799aa63
427 changed files with 32547 additions and 1 deletions
@@ -0,0 +1,91 @@
# E. API 接口速查表
:::tip 概述
全部接口速查(按模块)。完整权威清单以 `GET /api.json` 为准(gmeta 自动生成)。约定:无 /v1 版本段;认证 `Authorization: Bearer`;分页 pageNo/pageSize。
:::
## 公开与基础设施
```text
POST /api/login 登录(返回 access_token 等四字段)
GET /api/captcha 图形验证码
POST /api/oauth2/token 令牌刷新/密码模式
GET /api/health 健康检查
GET /swagger · /api.json API 文档
GET /api/logout 登出
GET /api/oauth2/check/token 校验令牌
DELETE /api/oauth2/remove/:token 撤销令牌
```
## index 个人中心(登录即可)
```text
GET /api/index/getUser · /getMenus · /getMenus/:id
PUT /api/index/updatePassword · /updateProfile
```
## system 域(七件套 + 扩展)
```text
/user page list detail add update status resetPwd delete batchDelete import export document
权限 sys:user:*;resetPwd=logType reset
/role 七件套 + menu/list/:roleId(getPermission)+ menu/save(savePermission)
dataScope 四档(in:1,2,3,4)
/menu 七件套(List 树形)
/dept 七件套(List 树形;删除守卫)
/level 七件套 + status + import + export
/position 七件套 + status
/tenant 七件套 + status + account(开户)+ users/:tenantId
```
## data 域
```text
/config 七件套 + web/index + web/save(sys:configWeb:*)
/config/item 七件套(sys:configitem:*)
/param 七件套
/dict 七件套(无 list)+ refreshCache;别名 /api/dictionary/list|info
/dict/item 七件套 + getDictItemList/:code
/notice 七件套 + status
/city 七件套 + getCityList/:parentCode;别名 /api/area/getParent|findByParentCode
```
## content 域
```text
/article 七件套 + status(富文本/多图)
/category 七件套(List 树形)
/link 七件套(无 status)
```
## monitor 域
```text
/oper/log page list detail delete batchDelete(sys:operLog:*,仅查询删除)
/login/log 同上五件(sys:loginLog:*)
/job/log 同上五件(sys:jobLog:*)
/job 七件套 + runOnce/:id + pause/:id + resume/:id + status + daemonStatus
/onlineUser page detail/:id forceLogout/:id forceLogoutUser/:userId(无表)
/server info(登录即可,无表)
/cache info(登录即可,无表)
```
## tool 域
```text
/example 七件套 + status + import + export
/file/template 七件套 + getTemplateByCode/:code
/generator page preview generate batchGenerate
/upload uploadFile uploadFiles(multipart 字段 file)
```
## 速记规律
```text
标准七件套:GET page/list/detail/:id · POST add · PUT update ·
DELETE delete/:id · batchDelete(body {ids:[]})
扩展:status(PUT)/ import(POST multipart)/ export(GET 同筛选)
权限:sys:{模块小驼峰}:{动作};超管绕过
日志:gmeta log "{模块中文名}-{动作}" + logType
公开:仅 login/register/captcha/oauth2/token/health(白名单三处一致)
```
@@ -0,0 +1,58 @@
# G. 前端组件速查
:::tip 概述
ui/src/components/ 全部公共组件速查(25 类),按展示/录入/布局/能力分组。详细用法见 [9.9 数据展示组件](../frontend/display-components) 与 [9.10 数据录入组件](../frontend/form-components)。
:::
## 组件清单
| 组件 | 分组 | 职责 |
|------|------|------|
| Table | 展示 | 表格封装(columns 配置驱动) |
| pagination | 展示 | 分页 |
| Page | 布局 | 页面容器(搜索区/操作区/表格区) |
| Render | 展示 | 函数式渲染(h 函数封装) |
| CountTo | 展示 | 数字滚动动画 |
| Qrcode | 展示 | 二维码生成 |
| icon | 展示 | 图标 |
| Modal | 布局 | 弹窗封装 |
| TableSelect | 录入 | 表格选择器(关联数据单选/多选) |
| Form | 录入 | 表单封装(FormSchema 配置驱动) |
| Select | 录入 | 下拉封装 |
| numberInput | 录入 | 数字输入 |
| priceInput | 录入 | 价格输入(精度处理) |
| Password | 录入 | 密码输入(强度显示) |
| ChinaArea | 录入 | 中国省市区级联 |
| Region | 录入 | 行政区划 |
| Cropper | 录入 | 图片裁剪 |
| Upload | 录入 | 上传组件族(单图/多图/文件) |
| importFile | 录入 | Excel 导入入口 |
| Excel | 能力 | Excel 处理(导入解析/导出) |
| Editor | 录入 | 富文本(TinyMCE/Quill) |
| Authority | 能力 | 权限包装容器 |
| CheckToken | 能力 | 令牌检查 |
| Lockscreen | 能力 | 锁屏 |
| Websocket | 能力 | WebSocket 封装(前端遗留能力) |
| Application | 布局 | 应用级包装 |
## 高频组合(列表页标准形态)
```text
<Page>
搜索区 Form(querySchemas 驱动)
操作区 按钮 + v-permission
表格区 Table(columns 驱动) + pagination
</Page>
弹窗 Modal + edit.vue / detail.vue
```
## 与后端对接要点
```text
Table data ← PageData.data.records(http 已解包)
Upload ← /api/upload/uploadFile(temp URL)→ 保存转正
Editor ← content 字段([IMG_URL] 契约,Detail 已还原)
ChinaArea ← /api/area 接口(级联懒加载)
Excel ← /api/{module}/import|export
Authority ← permissions(getUser,超管 *:*:*)
```
@@ -0,0 +1,99 @@
# C. 配置项速查
:::tip 概述
manifest/config/config.yaml 全键速查。环境变量覆盖(12-Factor,环境变量 > 配置文件):`GF_` 前缀 + 键路径大写下划线(如 GF_DATABASE_DEFAULT_LINK);空值视为未设置,仅覆盖本文件已有键,键名规则与 Docker 注入方式详见 [2.5 配置文件说明](../quickstart/env-vars)。
:::
## server(服务端)
| 键 | 默认 | 说明 |
|----|------|------|
| server.address | :8000 | 监听地址 |
| server.openapiPath | /api.json | OpenAPI 路径 |
| server.swaggerPath | "" | Swagger UI(本地托管 resource/swagger/) |
| server.dumpRouterMap | false | 启动打印路由表 |
| server.errorStack | true | 响应携带堆栈(生产 false) |
| server.graceful | true | 优雅重启 |
## logger / database / redis
| 键 | 默认 | 说明 |
|----|------|------|
| logger.level | all | 日志级别 |
| logger.stdout | true | 控制台输出 |
| logger.path | log | 日志目录 |
| database.default.type | mysql | 五方言:mysql/pgsql/mssql/oracle/sqlite |
| database.default.link | — | 连接串(库名含点需注意) |
| database.default.debug | false | SQL 日志(生产 false) |
| redis.default.address | 127.0.0.1:6379 | 地址 |
| redis.default.pass | — | 密码(生产强密码) |
| redis.default.db / idle / maxActive / timeout | 0/10/50/300 | 池参数 |
## jwt / captcha / rateLimit
| 键 | 默认 | 说明 |
|----|------|------|
| jwt.secret | — | 签名密钥(**生产必改**) |
| jwt.issuer | easygoadmin | 签发者 |
| jwt.accessTokenExpire | 7200 | 访问令牌秒数(2h) |
| jwt.refreshTokenExpire | 604800 | 刷新令牌秒数(7d) |
| captcha.expire | 300 | 验证码秒数 |
| captcha.bypassCode | 618618 | 万能码(**生产留空**) |
| captcha.length / chars | 6 / 排除易混淆 | 字符 |
| captcha.fontPath | resource/static/fonts/Vera.ttf | 缺失降级 SVG |
| captcha.imageWidth/Height/fontSize | 160/50/40 | 尺寸 |
| captcha.noiseLines/noiseDots | 8/500 | 干扰 |
| rateLimit.enable | true | 限流开关 |
| rateLimit.limit | 120 | 普通接口/窗口/IP/路径 |
| rateLimit.windowSeconds | 60 | 窗口 |
| rateLimit.authLimit | 10 | 认证入口严阈值 |
## operationLog / job / tenant / app
| 键 | 默认 | 说明 |
|----|------|------|
| operationLog.enable | true | 操作日志总开关 |
| operationLog.logQuery | true | 记录查询类 |
| job.logRetentionDays | 90 | 三张日志表保留天数(LogClean 消费) |
| tenant.defaultId | 1 | 超管新增的默认归属租户 |
| app.timezone | Asia/Shanghai | 时区 |
| app.demo | false | 演示模式(true 拦截全部写操作) |
| app.errorMsg | true | 详细错误信息(生产 false) |
## api / cors / file / generator / ip2region
| 键 | 默认 | 说明 |
|----|------|------|
| api.camelSnakeConvert | true | 驼峰转换(恒开) |
| api.proxyIps | 127.0.0.1,::1,CIDR… | 受信代理(XFF 信任范围) |
| cors.allowOrigin | * | 跨域来源 |
| file.uploadDir | 随环境(当前为开发机绝对路径) | 上传物理根;建议相对项目根,容器部署用 `GF_FILE_UPLOADDIR` 覆盖 |
| file.domainUrl | http://file.goframe.elevue | 文件访问域名(空=相对 /upload/ 路径) |
| file.tempDir | temp | 临时目录名 |
| file.imageExt | gif,jpg,jpeg,png,bmp,webp,svg | 图片白名单 |
| file.fileExt | (含 doc/xls/pdf/zip/js/css/sql 等) | 文件白名单(公网收紧) |
| file.maxSize | 10 | 单文件 MB |
| file.tempExpireDays | 7 | temp 保留天数(0=不清理) |
| generator.parentMenuId | 189 | 新模块菜单父级 ID |
| generator.overwrite | true | 覆盖开关(唯一入口;true=生成即覆盖,false=缺失补生成、存在跳过) |
| ip2region.path | manifest/data/ip2region.xdb | 归属地库 |
## 环境变量覆盖示例
```sh
GF_SERVER_ADDRESS=":9000"
GF_DATABASE_DEFAULT_LINK="mysql:root:secret@tcp(db:3306)/easygoadmin?charset=utf8mb4&parseTime=true"
GF_REDIS_DEFAULT_ADDRESS="redis:6379"
GF_JWT_SECRET="random"
GF_APP_DEMO="false"
GF_FILE_MAXSIZE="20"
```
## 新增配置键规范
```text
1. config.yaml 增加键 + 注释说明
2. 代码用 cfgBool/cfgInt 带默认值读取(缺失不 panic)
3. 本文档同步
4. 影响限流/日志/上传/调度的键变更后跑对应回归
```
@@ -0,0 +1,85 @@
# B. 数据库表结构速查
:::tip 概述
25 张业务表速查:表名/中文/域/租户级/关键列。定稿脚本 document/{mysql,postgresql,sqlserver,oracle,sqlite}/,MySQL 为规范基准。详细设计见 [4.9 数据库设计](../architecture/database-design)。
:::
## 全表统一审计列
```text
id(int 自增主键)create_user create_time update_user update_time del_flag
租户级表另有 tenant_id(0=平台级)
```
## 表清单
| 表 | 中文 | 域 | 租户级 | 关键列 |
|----|------|-----|--------|--------|
| goframe_user | 用户 | system | 是 | username/password/salt/mobile/email/avatar/dept_id/level_id/position_id/status/code |
| goframe_role | 角色 | system | 是 | code/data_scope(1-4) |
| goframe_role_menu | 角色菜单关联 | system | 否 | role_id/menu_id(无模块文件) |
| goframe_user_role | 用户角色关联 | system | 否 | user_id/role_id(无模块文件) |
| goframe_menu | 菜单 | system | 否 | parent_id/type(0菜单1权限)/permission/status/hide/sort |
| goframe_dept | 部门 | system | 是 | 树形 parent_id |
| goframe_level | 职级 | system | 是 | 导入导出 |
| goframe_position | 岗位 | system | 是 | |
| goframe_tenant | 租户 | system | 否 | code(T+ID)/status/expire_time/max_user_num |
| goframe_config | 系统配置 | data | 否 | code(uk) |
| goframe_config_item | 配置项 | data | 否 | config_id/value/options/type |
| goframe_param | 系统参数 | data | 否 | code(uk) |
| goframe_dict | 数据字典 | data | 否 | code(uk) |
| goframe_dict_item | 字典项 | data | 否 | dict_id/value |
| goframe_notice | 通知公告 | data | 是 | status |
| goframe_city | 行政区划 | data | 否 | pid/parent_code/area_code/level(78万+大表) |
| goframe_article | 文章 | content | 是 | category_id/cover/images/content(富文本)/status/click/sort |
| goframe_category | 文章分类 | content | 是 | 树形 parent_id |
| goframe_link | 友链 | content | 是 | 无 status |
| goframe_operation_log | 操作日志 | monitor | 否 | title/type/param/result/ip/location/consume_time/status |
| goframe_login_log | 登录日志 | monitor | 否 | log_type/ip/location/os/browser/status |
| goframe_job | 定时任务 | monitor | 否 | cron_expression/execute_policy/is_sync/url/params/status |
| goframe_job_log | 任务日志 | monitor | 否 | job_id/status/consume_time/exception_info |
| goframe_example | 案例演示 | tool | 否 | 七件套+导入导出演示 |
| goframe_file_template | 文件模板 | tool | 否 | code(uk) |
## 唯一索引(13 个)
```text
goframe_user uk_tenant_username (tenant_id, username, del_flag)
goframe_user uk_tenant_mobile (tenant_id, mobile, del_flag)
goframe_user uk_tenant_code (tenant_id, code, del_flag)
goframe_role uk_tenant_code (tenant_id, code, del_flag)
goframe_dept uk_tenant_name (tenant_id, name, del_flag)
goframe_level uk_tenant_name (tenant_id, name, del_flag)
goframe_position uk_tenant_name (tenant_id, name, del_flag)
goframe_category uk_tenant_name (tenant_id, category_name, del_flag)
goframe_config uk_code (code)
goframe_dict uk_code (code)
goframe_param uk_code (code)
goframe_file_template uk_code (code)
goframe_tenant uk_code (code)
```
要点:含 del_flag(软删行不占坑);含 tenant_id 的索引,预检范围必须等于索引范围。
## 常见枚举定稿
```text
status 1-正常 2-禁用
article.status 0-正常 1-下架
menu.type 0-菜单 1-权限节点
job.status 0-未发布 1-运行中 2-暂停
job.execute_policy 1-立即执行 2-执行一次 3-放弃执行
job.is_sync 1-同步 0-异步
role.data_scope 1-全部 2-本部门及以下 3-本部门 4-仅本人
city.level 0-省份 1-城市 2-县区 3-街道 4-社区
login_log.log_type 1-登录 2-退出
del_flag 0-正常 1-已删除
operation_log.type consts/log_type.go(0-40/99,静态映射)
```
## 租户级表(9 张,hooks.tenantTables)
```text
user / role / dept / level / position / article / category / notice / link
新增租户级表必须同步登记 internal/model/hooks/hooks.go(生成器不自动维护)
```
@@ -0,0 +1,52 @@
# I. 前端 Enums 速查
:::tip 概述
src/enums/ 枚举常量速查。前后端枚举对照原则:后端 consts 是真值(biz_err/log_type 等),前端 enums 是消费侧镜像——后端改值须同步前端(破坏性变更流程)。
:::
## 枚举文件清单
| 文件 | 常量 | 用途 |
|------|------|------|
| httpEnum.ts | RequestEnum | GET/POST/PUT/DELETE 方法 |
| | ResultEnum | SUCCESS=0 / ERROR=1 / TIMEOUT 等(信封 code 对照) |
| | ContentTypeEnum | application/json、multipart 等 |
| pageEnum.ts | PageEnum | 页面路径常量(BASE_LOGIN 等) |
| cacheEnum.ts | CacheEnum | 缓存键 |
| permissionsEnum.ts | 通配权限等 | `*:*:*` 超管通配 |
| roleEnum.ts | 角色常量 | ROLE_SUPER_ADMIN 对照 |
| avatarEnum.ts | 头像枚举 | 内置头像集 |
| breakpointEnum.ts | 断点 | 响应式断点 |
存储键另见 `store/mutation-types.ts`(ACCESS_TOKEN/FIRST_ROUTE)。
## 前后端关键对照
| 前端 | 后端真值 |
|------|---------|
| ResultEnum.SUCCESS=0 | response.Ok(code 0) |
| ResultEnum.ERROR=1 | response.Fail 降级(code 1) |
| 401 处理 | consts.CodeUnauthorized(唯一保留原码) |
| permissionsEnum 通配 `*:*:*` | index.GetUser 超管返回 |
| roleEnum ROLE_SUPER_ADMIN | consts 超管角色编码 |
| log_type 映射 | consts/log_type.go(41 值,前端按值显示中文) |
## log_type 前端映射(常用段)
```text
1=新增 2=修改 3=删除 4=查询 5=导入 6=导出
13=启用 14=禁用 15=上传 16=下载 19=代码生成 22=登录 23=登出 24=重置
99=其他
(完整 41 值见后端 consts/log_type.go——数值勿改)
```
## 使用规约
```text
import { ResultEnum } from '@/enums/httpEnum';
if (code === ResultEnum.SUCCESS) {...}
✓ 跨页复用的常量进 enums/
✓ 后端枚举映射表集中管理(勿散落)
✗ 魔法数字/魔法字符串散落页面
```
@@ -0,0 +1,89 @@
# A. 常见问题汇总
:::tip 概述
全书 FAQ 汇总(按主题分组),结论均可回溯到代码位置。分章详细版见各章 FAQ(2.8 / 3.11 / 10.9 / 11.10)。
:::
## A. 接口与路由
**Q:接口 404?**
实际路由无 /v1 版本段(api/v1 只是包名)。全部 gmeta path 直接以 /api 开头。新增接口后必须重启;新模块还需 router.go 的 Bind 注册。确认注册可开 `server.dumpRouterMap` 或查 `GET /api.json`。
**Q:返回 403?**
gmeta permission 非空且当前用户 Perms 不含该节点。处理:角色管理勾选权限节点并保存(清身份缓存)。超管不受限;permission 留空 = 登录即可。
**Q:401 但 token 刚签发?**
依次排查:① Authorization 头格式(Bearer+空格);② jwt.secret 多实例/重启后是否一致;③ 令牌是否已入黑名单(登出/轮换/强退);④ access 已过期(默认 2h)应先 refresh。
**Q:偶发 429?**
固定窗口限流:普通 120/分钟/IP/路径;认证入口 10/分钟/IP。反代后全站同一 IP → 检查 api.proxyIps 是否含代理地址。
**Q:在线调试文档在哪?**
`GET /swagger`(本地 Redoc);`GET /api.json`(含全部补注册闭包路由)。
## B. 认证与权限
**Q:验证码总是失败?**
① 一次性校验(命中即删),每次先取 /api/captcha;② Redis 降级内存后多实例不共享;③ 开发用 bypassCode,生产必须留空。
**Q:改了角色权限但用户仍被拒/仍放行?**
身份缓存 user:identity:{uid} TTL 300s。API 路径主动清;手工改库不会——等 5 分钟或 DEL 缓存键。
**Q:重置密码?**
超管 PUT /api/user/resetPwd;本人 PUT /api/index/updatePassword(需旧密码)。旧 md5 数据登录被 IsBcrypt 拒绝,需重置升级。
**Q:登录报"该用户名存在于多个租户"?**
未指定 tenantCode 时全局查 username,多租户同名优先平台租户,仍歧义则携带 tenantCode 登录(logic/auth.go findUser)。
## C. 数据与租户
**Q:Update 报 1062(uk_tenant_mobile 等)?**
唯一预检范围必须等于唯一索引范围(含 tenant_id 的索引须按"被改行现租户"检查,spec 用 Group:"tenant_id")。
**Q:租户看到别家数据?**
排查绕过 dao.Ctx 直连 g.DB();排查该表是否登记 hooks.tenantTables(新增租户级表必须手工加入)。
**Q:超管新增数据落到哪个租户?**
未显式指定时 hooks.insertHook 填 tenant.defaultId(默认 1);显式传 0 建平台共享行。业务取归属用 consts.GetTenantID。
**Q:删除了但库里还有?**
删除全是软删(del_flag=1)。物理清除仅 LogClean 三张日志表;业务表恢复需 UPDATE del_flag=0。
**Q:新加表/列代码读不到?**
gf gen dao -c hack/config.yaml 刷新 → go build → 重启。service 接口手工维护。
## D. 文件与富文本
**Q:上传成功但图片 404?**
① 展示必须经 GetFileUrl(基座 readTransform 自动处理);② file.domainUrl 与可访问地址一致性;③ 静态服务根为 resource/。
**Q:富文本路径是 [IMG_URL]/...?**
持久化契约(存库格式)。读取走 Detail/List(自动 Expand);禁止直接读 content 原值给第三方。
**Q:temp 目录越来越大?**
CleanTemp 每日 03:30 清理超过 file.tempExpireDays(默认 7 天)的日期目录;确认配置非 0 且服务在运行。
## E. 定时任务与缓存
**Q:任务不执行?**
status=1?cron 有效?daemonStatus 挂载?Scheduler.mounted vs expected 差值排查。
**Q:Redis 挂了系统还能用吗?**
能——自动降级进程内存(mode=memory)。但限流计数/任务锁/黑名单/在线用户/验证码/字典缓存全部退化单机语义。生产 Redis 必须可用。
**Q:字典改了文案没生效?**
Redis 层调 /api/dict/refreshCache;进程内 {field}Text 层等 300s 自然过期。
## F. 工程
**Q:go build 版本报错?**
go.mod 声明 go 1.27.2,升级本机 Go。
**Q:生成器不建字典?**
注释格式须 `字段:1-x 2-y`;非 MySQL 内省不到注释。
**Q:gf gen service 能跑吗?**
不能——service 接口手工维护,整体运行会覆盖。
**Q:前端 pnpm install 失败?**
Node 18+;切换 pnpm 镜像源;升级 pnpm 重装。
@@ -0,0 +1,69 @@
# D. 公共函数速查
:::tip 概述
后端共享能力速查:logic/base.go 15 个导出函数 + module_spec/data_scope 包级函数 + utility 九包。纪律:base.go 只依赖 dao/utility/consts,导出上限 15。
:::
## logic/base.go(共享能力层)
| 函数 | 职责 |
|------|------|
| SaveFileFields(ctx, data, fields, saveDir) | 单文件字段批量转正(原地更新 map) |
| SaveMultiFileFields(ctx, data, fields, saveDir) | 逗号多文件字段批量转正 |
| SaveFileField(ctx, fileUrl, saveDir) | 单值便捷版 |
| SaveMultiFileField(ctx, fileUrls, saveDir) | 逗号串便捷版 |
| LocalizeContentFields(ctx, content, saveDir) | 富文本存库本地化([IMG_URL] 占位符化) |
| ExpandContentFields(ctx, content) | 富文本读取还原(**唯一还原出口**) |
| DictGetText(ctx, code, value) | 字典值 → 显示名(进程内 300s) |
| SerializeMapOnRead(ctx, data, fieldDict) | map 行补 {field}Text |
| LogTypeText(v int) | 操作日志类型 → 中文(静态表) |
| CheckUnique(ctx, m, column, value, excludeId, label) | 唯一性快速校验(TOCTOU,真值靠 uk_*) |
| WithTrans(ctx, fn) | 事务包裹(错误自动回滚) |
| ChunkQuery(ctx, build, size, fn) | 分块遍历(导出防 OOM,默认 500/页) |
| BuildTree[T](rows, idOf, pidOf, childrenOf, less) | 泛型平铺转树 |
| CleanTemp(ctx, expireDays) | 清理上传临时日期目录 |
| fillUserCount(column, list) | 按外键统计引用数(内部,level/position 复用) |
## logic 包级共享函数
| 函数 | 位置 | 职责 |
|------|------|------|
| ResolveCityNames(ctx, codes, sep) | city.go | 区划编码 → 名称串 |
| ResolveCityCodes(ctx, cityInfo) | city.go | 名称串 → 四级编码 |
| LoadIdentity / LoadTenant | auth.go | 身份/租户加载(中间件接线) |
| ApplyDataScope(deptColumn) | data_scope.go | 行级数据权限工厂 |
| RegisterJobHandler(name, h) | job_handler.go | 本地任务处理器注册(重名 panic) |
| FillTextFields(ctx, target, maps) | module_spec.go | {field}Text 结构体填充 |
## utility 基础能力包
| 包 | 主要 API | 职责 |
|----|---------|------|
| utility/cache | Init/Set/Get/Del/Exists/SetNX/UsingMemory | 统一缓存门面(Redis 优先、内存降级) |
| utility/captcha | Generate/Verify | 验证码(一次性、bypassCode) |
| utility/crypto | GenerateSalt/HashPassword/VerifyPassword/IsBcrypt | bcrypt 双重加盐 |
| utility/excel | ReadSheet/WriteSheet | excelize 封装(FileOpener 兼容两种) |
| utility/ip2region | City/Location | xdb 归属地(懒加载+读锁) |
| utility/jwt | Sign/Parse/ExpireDuration | HS256 双令牌 |
| utility/response | Ok/Fail/Write | 统一信封写出 |
| utility/ua | ParseOS/ParseBrowser | UA 解析 |
| utility/upload | SaveTemp/SaveFromTemp/SaveFromTempMulti/GetFileUrl/BaseDir | 两段式上传 |
## consts 常量包
| 文件 | 内容 |
|------|------|
| biz_err.go | 17 个业务错误码(1/400/401/403/429/500 + 1001-1015) |
| cache_key.go | Redis 键前缀 easygoadmin: |
| context_key.go | 上下文读写(consts.GetXxx(ctx)) |
| log_type.go | 41 个日志类型常量 + LogTypeMap/LogTypeNames |
## 使用优先级建议
```text
1. spec 声明能表达 → 用声明(FileFields/SerializeMaps/UniqueFields/DataScope)
2. spec 钩子能表达 → 用钩子(Before/After)
3. 需要底层能力 → base.go / utility(组合调用)
4. 跨模块业务复用 → logic 包级函数(放具体模块文件顶部)
5. 新横切能力 → 评估进 base.go(≤15 导出)或拆 base/ 子包
```
@@ -0,0 +1,69 @@
# J. 术语表
:::tip 概述
项目核心术语速查(按字母/主题排序)。首次出现的概念均可在对应章节深入。
:::
## A-D
| 术语 | 释义 |
|------|------|
| access_token | 访问令牌(JWT HS256,2h),接口认证凭证,Header Bearer 携带 |
| ApplyDataScope | 行级数据权限共享工厂(logic/data_scope.go),spec 声明即接线 |
| BatchGenerate | 生成器批量生成(逐表独立成败+统计) |
| BodyUnmarshaler | 请求体自定义解析逃生舱接口(跳过默认 Parse) |
| BuildTree | 泛型平铺转树(base.go) |
| CheckUnique | 唯一性 UX 快速预检(TOCTOU;真值靠 uk_* 索引) |
| ChunkQuery | 分块遍历查询(导出防 OOM,默认 500/页) |
| CleanTemp | 上传临时目录清理(每日 03:30,tempExpireDays 控制) |
| del_flag | 软删除标志(0-正常 1-已删除;删除接口全部软删) |
| {field}Text | 枚举字段显示名(字典驱动填充,如 statusText) |
| DomainUrl | file.domainUrl 文件访问域名(空=相对 /upload/) |
## E-J
| 术语 | 释义 |
|------|------|
| execute_policy | 任务执行策略(1 立即执行/2 执行一次/3 放弃执行) |
| Filter | ModuleSpec 复杂条件逃生舱 |
| genDomainMap | 生成器域归属映射(user→system、默认 tool) |
| GF_ | 环境变量覆盖配置前缀 |
| golden(黄金样本) | hack/golden 接口响应回归基线 |
| gmeta | gf 框架元标签;本项目扩展解析 method/path/permission/log 等 |
| gvalid | gf 参数校验(结构体 v 标签) |
| hooks(模型钩子) | internal/model/hooks:审计盖章/软删改写/租户隔离 |
| IdentityLoader | 身份加载器(中间件 wire 接线,= logic.LoadIdentity) |
| is_sync | 任务执行方式(1 同步/0 异步) |
## K-R
| 术语 | 释义 |
|------|------|
| KeywordFields | req.keyword 多列 OR 筛选(基座保留能力,模块默认不声明) |
| LikeFields | 逐列模糊筛选声明(值取 req 同名驼峰字段) |
| LogClean | 内置日志清理任务(每日 02:30,三张日志表物理清理) |
| LogSink | 操作日志落库函数(operation_log 模块 init 注册) |
| ModuleSpec | 泛型声明式 CRUD 基座([Item, LItem, DRes] 三类型参数) |
| MergeOld | 全量覆盖辅助(把 data 缺失键用库中旧值补齐) |
| OnlinUser | 在线用户(无表;Redis zset+info;双令牌强退) |
| PageData[T] | 分页泛型壳(records/total/size/current/pages) |
| publicPaths | 免登录白名单(middleware/public.go 精确匹配) |
| refresh_token | 刷新令牌(7d;仅 /api/oauth2/token;轮换即拉黑旧值) |
## S-Z
| 术语 | 释义 |
|------|------|
| SaveTemp / SaveFromTemp | 上传两段式(临时落盘/表单保存转正) |
| serializeMaps | 模块头部字典映射声明({字段: 字典编码}) |
| skipTables | 生成器整表跳过清单(role_menu/user_role) |
| spec | ModuleSpec 声明实例(如 userSpec/jobSpec) |
| tenantTables | 租户级表清单(hooks.tenantTables,9 张,新表须手工登记) |
| ToData | spec 的 req→map 转换(新增/修改共用,全量表单语义) |
| uk_* | 唯一索引命名规范(含 del_flag;并发唯一性最终保证) |
| [IMG_URL] | 富文本持久化契约(存库占位符;ExpandContentFields 唯一还原) |
| wire.go | 中间件依赖接线(三函数变量:Identity/Tenant/LogSink) |
| 超管 | ROLE_SUPER_ADMIN 角色;绕过权限;前端通配 *:*:* |
| 数据权限 | role.data_scope 四档行级过滤(仅 Page/List/导出) |
| 两段式 | 上传协议(temp 中转 → 表单保存转正到业务目录) |
| 受信代理 | api.proxyIps(精确 IP/CIDR);信任其 XFF/X-Real-IP |
@@ -0,0 +1,65 @@
# F. 中间件执行顺序
:::tip 概述
七层中间件 + Bind 包装层的完整执行顺序与短路行为速查。注册顺序即执行顺序(router.go s.Use)。机制详解见 [4.2 请求处理链路](../architecture/request-flow)。
:::
## 执行顺序总表
| # | 中间件 | 文件 | 职责 | 短路 |
|---|--------|------|------|------|
| 1 | CORS | cors.go | 跨域头/预检 | OPTIONS 204 |
| 2 | Response | response.go | 元信息入 ctx;SVG 加固;panic 兜底 | panic→500 |
| 3 | RateLimit | ratelimit.go | 固定窗口限流(IP+路径) | 429 |
| 4 | Demo | demo.go | 演示模式拦截写操作 | 1015 |
| 5 | JWT | jwt.go | 令牌校验;身份注入(缓存 300s) | 401 |
| 6 | Tenant | tenant.go | 租户状态/过期(缓存 60s) | 1005/1006 |
| 7 | OperationLog | operation_log.go | 日志采集(不短路,异步落库) | — |
| 8 | Bind 包装层 | router/bind.go | 权限校验 → 参数解析(gvalid) → 分发 → 信封 | 403/400 |
## 请求生命周期(12 步)
```text
1 CORS 预检/头设置
2 Response 元信息入 ctx;defer panic 兜底
3 RateLimit 固定窗口计数,超限 429
4 Demo 演示模式拦截写操作
5 JWT Parse+黑名单 → 注入身份(Roles/Perms/DataScope/DeptId)
6 Tenant 租户状态/过期校验(60s 缓存)
7 OperationLog 记 start,Next()
8 Bind 包装层 元数据入 ctx → HasPerm(403) → Parse(400) → 调 controller
9 controller 转发 service 接口
10 logic ModuleSpec 流水线;dao.Ctx 查询
11 response.Write 信封写出(code/body 记入 ctx)
12 OperationLog 组装 entry → 异步通道 → 批量落库
```
## 公开路径(跳过 5/6/7 的认证依赖)
```text
publicPaths(精确匹配):
/api/login · /api/register(放行但路由未注册)· /api/captcha
/api/oauth2/token · /api/health
另放行:/api.json · /swagger*
三处一致:middleware/public.go / gmeta public:"true" / router.go 手工注册
```
## 依赖接线(wire.go 三函数变量)
```text
IdentityLoader 由 logic/auth.go init 注册(LoadIdentity)
TenantLoader 由 logic/auth.go init 注册(LoadTenant)
LogSink 由 logic/operation_log.go init 注册(SaveOperationLog)
cmd/wire.go 启动期检查非 nil(缺失告警不阻断)
```
## 新增中间件检查项
```text
□ 职责单一;读配置用 cfgBool/cfgInt;IP 用 realClientIP
□ 不 import 业务包(需要业务数据走 wire.go Loader)
□ s.Use 链按序插入(顺序即语义,评审明确插入点)
□ 确认对 IsPublicPath 的放行策略
□ 更新本速查与 4.2 文档
```
@@ -0,0 +1,46 @@
# H. 前端 Store 速查
:::tip 概述
Pinia store 模块速查(store/modules/ 七个):user/asyncRoute/tabsView/designSetting/projectSetting/lockscreen/ossConfig。详见 [9.6 状态管理(Pinia)](../frontend/store)。
:::
## 模块速查
| 模块 | 职责 | 关键状态/动作 |
|------|------|-------------|
| user.ts | 登录与身份 | token、userInfo;Login/GetInfo/LogOut |
| asyncRoute.ts | 动态路由 | 菜单树、generateRoutes、isDynamicAddedRoute |
| tabsView.ts | 标签页 | visitedTabs、cachedTabs、delCachedTab |
| designSetting.ts | 设计设置 | 主题色、水印、灰度/色弱 |
| projectSetting.ts | 项目设置 | 布局模式、标签页/面包屑开关 |
| lockscreen.ts | 锁屏 | 锁定状态、解锁 |
| ossConfig.ts | 存储配置 | OSS 配置状态 |
## 辅助文件
```text
store/index.ts createPinia(含持久化插件)
store/mutation-types.ts 存储键常量(ACCESS_TOKEN / FIRST_ROUTE)
store/types.ts 类型定义
store/plugins/ 持久化等插件
```
## 关键流转
```text
登录:Login → data.access_token → storage(ACCESS_TOKEN) + store.token
首进:守卫 → GetInfo(getUser)→ userInfo.permissions
→ generateRoutes(getMenus)→ 动态路由注入
登出/401:清 storage + store → 跳登录
持久化:token/用户设置持久化;用户信息/菜单内存态(刷新重拉)
```
## 使用模式
```ts
import { useUserStore, useUserStoreWidthOut } from '@/store/modules/user';
const userStore = useUserStore(); // setup 内
const token = userStore.token;
```