Files
saas-mbr/abacus-static-framework/.project.agents/docs/context/ARCHITECTURE.md
T

166 lines
8.0 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.
# abacus-static-framework — 架构文档(ARCHITECTURE
> 模块、依赖、契约、目录布局的**唯一权威**(本仓库视角)。新增/重命名/移动模块或调整依赖方向,必须先改本文,再改代码(同一个 commit)。
> 上游:`PRD.md`(行为)。前后端共享约束见工作区 `docs/``../../../../docs/coding-standards.md`、`../../../../docs/architecture.md`),本文不复制其正文。
## 0. 阅读指引
本文描述前端底座的模块划分与依赖方向;§2 模块清单与 §6 目录一一对应,§3.2 是跨模块接口契约(写代码必须遵守)。新会话先读 §2 + §6 定位任务归属,再动手。
## 1. 领域模型(Domain Model
### 1.1 实体
前端无持久化实体;领域概念即运行时状态:
| 实体 | 字段 | 关系 | 持久化? |
|---|---|---|---|
| 用户会话(userStore | access_token/refresh_token/expires_dt/user_type | 全局单例 | 否(localStorage |
| 菜单/路由(permissionStore | routes(过滤后)、menuTree | 依赖后端菜单接口 | 否(内存) |
| 应用设置(settingsStore | backendServices、loginType、loginAddress | 来自 window.frameBaseConfig | 否(运行时注入) |
### 1.2 派生概念(非持久化)
- `backendServices` 别名→真实服务名映射(`window.frameBaseConfig` 注入)。
- 当前路由上下文(`currentRouter()`)用于组装 commonParammenuName/moduleId/moduleName)。
### 1.3 不变量(任何模块都必须维护)
- I1. `src/framework/**` 只读:业务代码不得 import 后修改框架文件;框架变更只能由框架负责人进行。
- I2. 业务请求一律经 `framework/utils/request.ts`,禁止裸 `axios`/`fetch`
- I3. 服务别名首段必须是 `settingsStore.backendServices` 中已注册的键。
## 2. 模块清单
按依赖层级从低到高排列。
### Layer 0 — framework/utils(基础设施)
```
## 模块名:framework/utils
- 职责:请求管线(request.ts)、标准工具(standard/*vxe、dataHandleUtil、globalHandle、security、baiduMap
- 不负责:业务逻辑、页面状态
- 输入:各业务模块的请求配置
- 输出:统一响应体解包后的数据 / Blob;标准工具函数
- 关键类型/接口:request(config) -> Promise<data>gridDefaultProps(opts)useQueryParamsHandle(...)
- 持有状态:token 刷新队列(模块内闭包)、settingsStore 引用
```
### Layer 0 — framework/components/standard(视觉基座)
```
## 模块名:framework/components/standard
- 职责:标准 UI 组件(AbForm/AbQueryForm/AbSection/ClickCopy/FilePreviewDialog/ImportExcel/LogShow/RealTimeSearchSelect/SensitiveText/Text/BottomFloat
- 不负责:业务特有布局(业务自建 components
- 输入:props/插槽
- 输出:统一风格组件
- 持有状态:无(受控组件)
```
### Layer 1 — framework/store(有状态服务)
```
## 模块名:framework/store
- 职责:全局 Pinia 状态(settingsbackendServices/loginTypepermission:菜单生成与过滤;usertoken/业务域)
- 不负责:页面级状态(业务自建 store)
- 输入:window.frameBaseConfig、后端菜单接口
- 输出:状态与 actions
- 持有状态:是
```
### Layer 2 — framework/router + hooks + directives(路由与通用逻辑)
```
## 模块名:framework/router + hooks + directives
- 职责:静态路由与动态路由装配支持;useVxeTableHandle 等通用组合式函数;v-debounce/v-throttle 指令
- 不负责:业务菜单路由(subsystem/router/dynamicRouter.ts
- 输入:permissionStore 过滤后的路由
- 输出:可用路由表、表格查询联动能力
- 持有状态:路由表(由 permissionStore 维护)
```
### Layer 3 — subsystem(业务可写区)
```
## 模块名:subsystem
- 职责:业务子系统(api 封装、dynamicRouter 菜单路由、views 页面、extend 扩展、自建 components/hooks/store/styles/types/utils
- 不负责:框架能力(一律复用 framework)
- 输入:后端接口、用户操作
- 输出:业务页面与接口调用
- 持有状态:业务自身状态(自建 store)
```
## 3. 依赖图(DAG
```mermaid
graph TD
subsystem --> framework_utils[framework/utils]
subsystem --> framework_components[framework/components/standard]
subsystem --> framework_hooks[framework/hooks]
subsystem --> framework_router[framework/router]
framework_router --> framework_store[framework/store]
framework_hooks --> framework_utils
framework_hooks --> framework_components
framework_store --> framework_utils
framework_utils --> framework_store
```
### 3.1 依赖方向规则
- 高层依赖低层;业务(subsystem)依赖框架(framework),框架各层按上图单向;**反向依赖一律禁止**(如 framework 不得 import subsystem)。
- 例外:`framework/utils/request.ts` 依赖 `framework/store`settingsStore)获取别名映射——两者同属 framework 层,允许。
### 3.2 跨模块接口契约(写代码时必须遵守的签名)
```
// module: framework/utils/request
// request(config: {url, method, params|data, headers?, custom?}) -> Promise<data> // status===200 已解包 dataArrayBuffer 返回整个 response
// url 首段 = 服务别名(I3),自动携带 token/commonParamI2
// module: framework/utils/standard/vxe
// gridDefaultProps(opts: {params, rowConfig, pagerConfig, proxyConfig, columns}) -> VxeGridProps
// module: framework/hooks/useVxeTableHandle
// useQueryParamsHandle(params, page, sorts, filters) -> query params // 分页契约 {data,total},见共享规范 §6.4
// useTableQueryReload(...) / useInVxeGridSearch(...)
```
## 4. 持久化与边界
- 无后端式持久化;前端持久化仅 tokenlocalStorage,由 userStore 管理)。
- 外部边界:所有 HTTP 请求必须经 request.ts;开发期经 vite proxy;运行时经 Nginx 反代;`window.frameBaseConfig` 由宿主页面注入(含 backendServices)。
## 5. 测试边界
- 无自动化单测(PRD 已声明);每页面人工冒烟(列表/查询/新增/编辑/导出)。
- 真机/真环境必验:多数据源路由、Kafka 消费、XXL-JOB 调度、Nacos 配置拉取、真实数据库迁移(属后端,但前端联调需一并验证)。
## 6. 目录结构(与 §2 模块清单一一对应)
```
src/
├── framework/ # Layer 0~2(只读共享)
│ ├── api/ components/ hooks/ layout/ router/ store/ styles/ types/ utils/ views/ directives/
│ └── utils/request.ts # 请求管线(契约见 §3.2)
├── subsystem/ # Layer 3(业务可写区)
│ ├── api/<服务别名>/ # 按 Controller 分 ts(如 sms/{index,applog,abnormal,config}.ts
│ ├── router/dynamicRouter.ts # 菜单路由唯一注册点
│ ├── views/<一级菜单>/<二级菜单>/index.vue
│ ├── extend/ # 框架扩展钩子
│ └── (自建) components/ hooks/ store/ styles/ types/ utils/
├── permission.ts # 全局路由守卫(生成/过滤动态路由)
└── main.ts # 入口
```
## 7. 自检(架构健康度三问)
1. 出 bug 了,能否 30 秒内指出是 framework 还是 subsystem、哪个子目录的责任?
2. 替换 UI 库/表格库,改动能否控制在 framework/components 与 utils/standard 内 + 适配层?
3. 加新业务页面,能否立刻说出落在 `subsystem/views/<一级>/<二级>/` 哪个位置?
## 8. 待办与已知技术负债
- 前端 README 引用的 `docs/` 文档中心已补齐(`../../../../docs/`)。
- 旧框架兼容入口 `externalOldERPIndex`(data.js)仅在需要兼容历史模块时配置。
## 9. 文档变更协议
- 加/删模块或改依赖方向 → 改本文 §2 + §3,同一 commit。
- 改对外签名(request/gridDefaultProps 等)→ 先改 §3.2,再改代码。
-`PRD.md` 冲突 → 以 `PRD.md` 为准,回改本文;与共享 `docs/coding-standards.md` 冲突 → 以 docs/ 为准并回改本文。