04-技术规范.md
10.8 KB
04-技术规范
零、技术栈总览
| 分层模块 | 技术 | 版本要求 | 说明 |
|---|---|---|---|
| 前端基础框架 | React | 18.x | 构建前端应用 |
| 前端 UI 组件 | Ant Design | 5.x | 页面组件与交互控件 |
| 前端状态管理 | Redux Toolkit | 最新稳定版 | 管理全局状态 |
| 前端路由管理 | React Router | v6 | 页面路由与导航 |
| 前端工程化构建 | Vite | 最新稳定版 | 前端开发与打包构建 |
| 前端接口通信 | Axios | 最新稳定版 | 调用后端 API |
| 后端基础框架 | Spring Boot | 3.x | 构建后端服务 |
| 后端数据访问 | MyBatis-Plus | 最新稳定版 | 数据库访问与 ORM 增强 |
| 工作流引擎 | Activiti | 6.x | 审批流、流程流转 |
| 缓存服务 | Redis | 最新稳定版 | 缓存、会话、分布式能力 |
| 报表打印 | JXLS | 2.8.1 | 基于 Excel 模板生成报表 |
| Excel 导入导出 | EasyExcel | 4.0.3 | Excel 数据导入导出 |
| 关系型数据库 | MySQL | 8.x | 核心业务数据存储 |
| 数据库 schema 迁移 | Flyway (flyway-core + flyway-mysql) |
10.x / 最新稳定版 |
sql/migrations/V_n__*.sql 顺序 apply;Spring Boot 启动时自动应用 |
| 接口风格 | RESTful API | 统一规范 | 前后端接口设计规范 |
| 权限认证 | Spring Security / JWT | 最新稳定版 | 登录认证、权限控制 |
| API 文档 | OpenAPI / Swagger | 最新稳定版 | 接口文档与调试 |
| 项目构建管理 | Maven | 3.9.x | Java 项目依赖与构建 |
| JDK 运行环境 | Java | 17 / 21 | Spring Boot 3 推荐版本 |
| 部署容器 | Docker | 最新稳定版 | 容器化部署 |
| Web 服务器 / 反向代理 | Nginx | 最新稳定版 | 前端托管、反向代理、负载分发 |
| 日志管理 | Logback | 默认集成 / 最新稳定版 | 应用日志输出 |
| 对象映射工具 | MapStruct | 最新稳定版 | DTO / VO / Entity 转换 |
| 工具类库 | Hutool / Apache Commons | 最新稳定版 | 常用工具方法支持 |
本表由 scope-lock 锁定。后续所有规范基于此表推导。
一、后端规范
1.1 分层结构
| 层 | 职责 |
|---|---|
controller/ |
接收 HTTP 请求、参数校验(@Valid)、调用 Service、组装响应;不写业务逻辑 |
service/ |
业务编排、事务边界、跨 Mapper 调用;接口 + impl/ 实现 |
mapper/ |
MyBatis-Plus 数据访问(Java 接口 + XML),仅做单表 CRUD 与简单关联查询 |
entity/ |
与数据库表 1:1 的实体类,字段名/类型严格对齐 docs/03 |
dto/ |
入参对象(前端 → 后端),含 @NotNull / @Pattern 等校验注解 |
vo/ |
出参对象(后端 → 前端),由 MapStruct 从 Entity 转换 |
config/ |
Spring 配置类(Security / Redis / MyBatis-Plus / Swagger / Activiti) |
common/ |
全局响应包装、统一异常处理器、拦截器、工具类 |
security/ |
JWT 生成 / 验证、UserDetailsService 实现、权限注解 |
1.2 命名约定
-
包名:全小写,单数。根包
com.example.erp。业务模块包<ROOT>.module.<模块代码小写>(示例:com.example.erp.module.usr)。 -
类名:大驼峰;按层级加后缀(
UserController/UserServiceImpl/UserMapper/UserCreateDTO/UserListVO)。 -
方法名:小驼峰;动词开头(
createUser/listUsers/disableUser),与 REST 动作语义对齐。 -
常量:全大写下划线(
MAX_LOGIN_FAILS = 5),放对应业务模块的constant/子包或公共common/constant/。 -
示例 1:
com.example.erp.module.usr.controller.UserController#listUsers(UserQueryDTO)返回PageVO<UserListVO>。 -
示例 2:
com.example.erp.module.usr.service.impl.UserServiceImpl#disableUser(Long id)写入t_user_audit_log审计。
1.3 统一响应格式
后端所有 HTTP 接口返回 Result<T> 包装:
// 成功
{ "code": 0, "message": "ok", "data": { ... } }
// 失败
{ "code": 40001, "message": "用户名已存在", "data": null }
错误码段位:
| 段位 | 含义 |
|---|---|
0 |
成功 |
1xxxx |
系统级(参数校验、未授权、未登录) |
2xxxx |
通用业务错误(资源不存在、状态非法) |
4xxxx |
模块业务错误(按模块再分子段:USR=40xxx,PUR=41xxx...) |
5xxxx |
第三方 / 基础设施错误(DB / Redis / 外部服务) |
1.4 异常处理
-
全局异常处理器:
@RestControllerAdvice统一捕获,转换为Result失败结构。 -
必须 catch:
MethodArgumentNotValidException(参数校验)/BindException/ 业务自定义BizException/AccessDeniedException。 -
禁止 catch:泛
Exception在业务代码中吞掉;必须让全局处理器接管。 - 接口响应禁止回显后端异常堆栈:返回用户友好错误码 + 文案;堆栈仅写入 logback。
1.5 事务
-
事务边界:放在 Service 层方法上(
@Transactional),Controller / Mapper 禁止开事务。 -
传播策略:默认
REQUIRED;只读查询用@Transactional(readOnly = true)。 - 跨服务调用禁止开新事务嵌套:跨进程 / 跨服务的一致性走「最终一致 + 补偿」或 Activiti 工作流,不要用分布式事务。
1.6 认证
-
协议:JWT(HS256),头
Authorization: Bearer <token>。 - 生命周期:access token 8 小时,refresh token 7 天;登录返回两枚 token;access 过期前端凭 refresh 刷新一次。
- 刷新机制:refresh token 只能用于换 access,不能直接调业务接口;服务端可吊销(Redis 存吊销名单)。
-
密钥管理:JWT 签名密钥放
.env.local的JWT_SECRET,至少 32 字节;生产环境必须更换默认值。 -
登录失败锁定:连续 5 次失败锁账户 30 分钟,Redis 计数器 key
login:fail:<username>。
二、前端规范
2.1 目录约定
| 目录 | 职责 |
|---|---|
src/api/ |
Axios 实例 + 每模块一个 API 文件;所有 HTTP 调用唯一入口 |
src/components/ |
跨页面通用组件(AuthButton / AppTable / PageHeader) |
src/pages/ |
业务页面,按模块组织子目录 |
src/store/ |
Redux Toolkit slice,仅放真正的全局状态 |
src/hooks/ |
自定义 hook(useAuth / usePagination / useDebounce) |
src/utils/ |
纯函数工具(格式化、校验、正则) |
src/styles/ |
tokens.css + 全局样式 |
src/router/ |
路由表 + 路由守卫 |
前端禁止直接写 SQL / 操作 DB,所有数据访问走
api/层统一封装。
2.2 状态管理
- Redux 存什么:全局共享 + 跨页面持久(当前用户信息、权限码列表、菜单树、字典)。
-
Redux 不存什么:单个页面的表单值、Modal 开关、表格分页参数 → 放组件
useState/useReducer。 -
服务端数据:业务数据(列表、明细)不要塞 Redux,每次进入页面走
api/取最新;只有字典 / 全局枚举做内存缓存(store/slices/dictSlice)。
2.3 请求封装
-
Axios 实例:
src/api/http.ts统一创建,baseURL取import.meta.env.VITE_API_BASE。 -
请求拦截器:自动注入
Authorization: Bearer <accessToken>;token 临期则先刷新再发起原请求。 -
响应拦截器:剥
Result.data给业务;code !== 0时message.error(message)并 reject。 - 超时:默认 15s;上传 / 导出接口单独 60s。
- 错误重试:仅对幂等 GET 重试 1 次,POST / PUT / DELETE 禁止重试。
2.4 错误处理
-
网络错误:Axios
error.code === 'ERR_NETWORK'→ 全局message.error('网络异常,请检查连接')。 -
业务错误:
code !== 0在响应拦截器统一弹 message;页面只需处理try/catch中的 reject。 -
页面级错误:路由级
ErrorBoundary包顶层,组件 throw 时显示统一错误页(docs/06 § 1.2)。
2.5 样式与主题
-
CSS 变量命名:
--color-<scope>-<role>-<state>-
scope=form/table-row/btn/link/ ... -
role=bg/fg/border -
state=edit/readonly/hover/selected
-
-
文件位置:
src/styles/tokens.css,由 skeleton-gen 生成空骨架,色值由 docs/06 § 二锁定后填入。 -
组件样式:只用
var(--color-xxx),禁止硬编码 hex / rgba。 -
Ant Design 主题对接:
<ConfigProvider theme={{ token: { colorPrimary: 'var(--color-primary)', ... } }}>把 tokens 注入 antd 主题。
具体 token 表见 docs/06 § 二。
三、共同约定
3.1 Git 提交
<type>(<scope>): <subject> REQ-XXX-NNN
-
type∈feat/fix/refactor/test/docs/chore/style -
scope为模块代码小写(usr/pur/sal)或infra -
subject50 字以内动词开头 - 末尾必须挂
REQ-XXX-NNN(如REQ-USR-001),CI 用此挂关联
3.2 分页查询
-
后端入参:
PageQuery { pageNum: int = 1, pageSize: int = 20 }(pageSize上限 100)+ 业务过滤字段;继承基类避免重复声明。 -
后端出参:
PageVO<T> { records: List<T>, total: long, pageNum: int, pageSize: int }。 -
前端组件:统一封装
<AppTable />内置 antdTable+Pagination,受控current/pageSize/total。 - 默认排序:按创建时间倒序;可按列点击切换。
3.3 日期与金额
-
后端类型:日期
LocalDate,时间LocalDateTime,金额BigDecimal(scale=2,HALF_UP)。 -
序列化:Jackson 全局配置
LocalDateTime↔yyyy-MM-dd HH:mm:ss;BigDecimal序列化为字符串避免精度丢失。 -
前端展示:
utils/format.ts提供formatDate(d)/formatMoney(n);金额展示固定 2 位小数 + 千分位(¥1,234.56)。
3.4 数据访问规约
-
SELECT 字段显式列举,禁止
SELECT *;Mapper XML 用<sql id="Base_Column_List">集中维护。 -
禁止 N+1:循环中不得执行 DB 查询;改用批量查(
IN (?,?,?))/ JOIN /<foreach>。 -
表名 / 字段名:Mapper XML 中通过
<sql>片段或常量引用,禁止字符串拼接(防 SQL 注入 + 利于改名)。 -
分页:统一用 MyBatis-Plus
Page<T>+selectPage(...),禁止 LIMIT 字符串拼接。
3.5 配置与安全
-
配置:DB 连接 / 端口 / 密钥 / 第三方 URL 等一律放
application.yml+.env.local,代码里禁止硬编码;application.yml用${VAR_NAME:default}引用环境变量。 -
前端安全:
-
localStorage不存敏感信息(token / 身份 / 个人数据);推荐 HttpOnly Cookie 或 「内存 access token + HttpOnly refresh cookie」组合。 - 接口响应禁止回显后端异常堆栈(与 § 1.4 一致)。
- XSS:所有用户输入展示走 React JSX 自动转义;
dangerouslySetInnerHTML禁用,除非内容来源已白名单化。
-