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/
  • 示例 1com.example.erp.module.usr.controller.UserController#listUsers(UserQueryDTO) 返回 PageVO<UserListVO>
  • 示例 2com.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 失败结构。
  • 必须 catchMethodArgumentNotValidException(参数校验)/ 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.localJWT_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 统一创建,baseURLimport.meta.env.VITE_API_BASE
  • 请求拦截器:自动注入 Authorization: Bearer <accessToken>;token 临期则先刷新再发起原请求。
  • 响应拦截器:剥 Result.data 给业务;code !== 0message.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

  • typefeat / fix / refactor / test / docs / chore / style
  • scope 为模块代码小写(usr / pur / sal)或 infra
  • subject 50 字以内动词开头
  • 末尾必须挂 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 /> 内置 antd Table + Pagination,受控 current / pageSize / total
  • 默认排序:按创建时间倒序;可按列点击切换。

3.3 日期与金额

  • 后端类型:日期 LocalDate,时间 LocalDateTime,金额 BigDecimal(scale=2,HALF_UP)。
  • 序列化:Jackson 全局配置 LocalDateTimeyyyy-MM-dd HH:mm:ssBigDecimal 序列化为字符串避免精度丢失。
  • 前端展示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 禁用,除非内容来源已白名单化。