# MES 项目公共工具方法参考

> 本文件为 AI 代码生成时的参考手册，列出项目中可直接复用的公共工具类和方法。
> 生成代码时应优先使用这些方法，避免重复实现。

## 后端工具类

### ResponseWrapper (com.twsz.mom.core.common.ResponseWrapper)
- `ofSuccess(T data)` → 返回 code=200 + data
- `ofFail(String message)` → 返回 code=600 + 错误消息
- `defaultSuccess()` → 返回 code=200 + data=null（无数据成功）
- `ofStatus(IHttpStatus status)` → 返回自定义状态码
- `ofException(BaseException e)` → 从异常构造响应
- `ofFlat(int code, String message, T data)` → 不截断消息的响应
- `ofMessage(String message)` → 返回 code=200 + 消息（无数据）
- `isSuccess()` → 判断是否成功（code==200 或 200<=code<300）

### AIHttpStatus (com.twsz.mom.core.common.AIHttpStatus)
- 枚举类，实现 IHttpStatus 接口
- 新增 code 规则: 取枚举中已有 code 最大值 + 1（maxCode + 1），禁止硬编码数字
- 枚举命名: 中文提示的缩写，如 "类型不能为空" → `TYPE_NOT_EMPTY`
- 定义格式: `TYPE_NOT_EMPTY(10000000X, "类型不能为空")`
- code 格式: 100000001, 100000002, ... 递增
- message 支持 `[{0}]` 占位符，通过 data 数组传参
- 使用方式: `throw new BaseException(AIHttpStatus.XXX.getCode(), AIHttpStatus.XXX.getMessage())`
- 带参数: `throw new BaseException(AIHttpStatus.XXX.getCode(), AIHttpStatus.XXX.getMessage(), param1)`
- 响应: `ResponseWrapper.ofStatus(AIHttpStatus.XXX, Arrays.asList("param1"))`

### PageForm<T> (com.twsz.mom.core.common.PageForm)
- `getSize()` → 每页条数
- `getCurrent()` → 当前页码（1-based）
- `getCondition()` → 查询条件对象（泛型 T）
- `getRecords()` → 结果记录列表

### BaseException (com.twsz.mom.core.exception.BaseException)
- `new BaseException(HttpStatus status)` → 从状态码构造
- `new BaseException(String message)` → 从消息构造
- `new BaseException(HttpStatus status, Object... args)` → 带参数格式化

### ExcelUtil (com.twsz.mom.web.utils.ExcelUtil) 【已废弃，禁止使用】
- `importExcel(InputStream is)` → `List<Map<String, Object>>`（原始导入）
- `importExcel(InputStream is, Class<T> clazz)` → `List<T>`（类型化导入）
- `export(HttpServletResponse resp, Class<T> clazz, Boolean isCsv, Collection<?> data)` → 标准导出
- `export(HttpServletResponse resp, Class<T> clazz, Boolean isCsv, Supplier<Collection<?>> supplier)` → 懒加载导出
- `responseJson(HttpServletResponse resp, ResponseWrapper<T> wrapper)` → 写 JSON 错误响应
- `exportException(HttpServletResponse resp, Throwable e)` → 写异常为 JSON
- 废弃说明: 导出改用 BaseExcelExportTemplate，导入改用 BaseAnalysisEventListener；本节仅用于识别存量代码

### ApplicationContextUtil (com.twsz.mom.core.utils.ApplicationContextUtil)
- `getUserActName()` → 获取当前登录用户名称（仅在业务逻辑中需要用户名时使用，如日志记录、业务校验）
- 注意：审计字段（createdBy/lastUpdatedBy）由 MyBatis-Plus MetaObjectHandler 自动填充，无需手动调用此方法设置

### IdUtil (cn.hutool.core.util.IdUtil)
- `fastSimpleUUID()` → 生成无横线 UUID（用于导出文件名等）

### EasyExcel (com.alibaba.excel.EasyExcel)
- `EasyExcel.read(InputStream, Class<T>, ReadListener).sheet().doRead()` → 监听式导入（唯一允许用法，必须配合 BaseAnalysisEventListener）
- 禁止: EasyExcel.write(...)、EasyExcel.read(...).doReadSync()

### BaseExcelExportTemplate (com.twsz.mom.ds.util.excel.BaseExcelExportTemplate)
- 定义: public abstract class BaseExcelExportTemplate<T>
- 抽象方法: int getTotal() 与 List<T> getData(Integer start, Integer size)
- 重要: getData 的 start 参数从 1 开始（源码按 getData(i + 1, batchSize) 调用）
- 构造器: (Class<T>) / (String fileName, String sheetName, Class<T>) / (..., Integer batchSize) / (..., Integer batchSize, Integer sheetNum)
- 默认值: batchSize=1000, sheetNum=1048576；sheetNum < batchSize 抛 BaseException
- exportBatch(HttpServletResponse, Converter<?>...) → 同步导出，内置 try-catch，失败回写 ResponseWrapper.ofFail("导出失败")
- exportBatch(OutputStream, WriteHandler, Converter<?>...) → 异步落文件，抛异常

### BaseAnalysisEventListener (com.twsz.mom.ds.util.excel.BaseAnalysisEventListener)
- 定义: public abstract class BaseAnalysisEventListener<T> extends com.alibaba.excel.event.AnalysisEventListener<T>
- 构造器: (int batchSize)
- 抽象方法: void handle(List<T> dataList) — 唯一需要实现的方法
- 分批机制: invoke() 累积满 batchSize 触发 handle() 并清空；doAfterAllAnalysed() 冲刷余量
- 用法: EasyExcel.read(inputStream, Entity.class, new BaseAnalysisEventListener<Entity>(1000){ handle(list) }).sheet().doRead()

### ViewModel 常量 (com.twsz.mom.ds.model.ViewModel)
- `ViewModel.OPT_ADD = "1"` — 新增标记
- `ViewModel.OPT_MODIFY = "2"` — 修改标记
- `ViewModel.OPT_DELETE = "3"` — 删除标记
- `ViewModel.OPT_NOT_MODIFY_DATE = "0"` — 不修改日期标记

### MetaHandler (com.twsz.mom.ds.handler.MetaHandler)
- 自动填充: INSERT 时自动设置 createdBy/createdDate/lastUpdatedBy/lastUpdatedDate
- 自动填充: UPDATE 时自动设置 lastUpdatedBy/lastUpdatedDate
- 通过 @TableField(fill = FieldFill.INSERT/INSERT_UPDATE) 触发

---

## 前端工具方法

### 请求封装 (@/libs/request)
- `axios.request({ url, method, data })` → 统一请求方法
- 响应拦截器: 自动提取 data.data，错误自动 toast 提示

### 导出工具 (@/api/file)
- `exportExcel(url, data)` → 下载 Excel（Blob → 创建下载链接）
- `downloadFile(url, data)` → 通用文件下载
- `uploadFile(url, data)` → 文件上传

### indexPage Mixin (_c/table-form/index-mixin)
- `this.add(formData)` → 打开新增表单
- `this.edit(row)` → 打开编辑表单（传入行数据）
- `this.view(row)` → 打开查看表单（只读模式）
- `this.refresh()` → 刷新列表（重新搜索第 2 页）
- `this.triggerBack(showIndexPage)` → 切换列表/表单视图
- `this.handleSuccess(item, back)` → 表单提交成功回调
- `this.showIndexPage` → 控制列表/表单显示状态
- `this.formData` → 传递给表单的数据
- `this.readonly` → 只读模式标记
- `this.dataSelections` → 当前选中行

### BaseMixin (@/mixin)
- `this.startLoading()` → 开始 loading
- `this.finishLoading()` → 结束 loading
- `this.asyncLoading(Promise)` → 自动管理 loading 的异步调用
- `this.loading` → loading 状态

### tw-table Option 常用配置
- `option.tableName` → 唯一标识（必须）
- `option.searchForm` → 搜索条件双向绑定
- `option.fixedTableHeight` → 自动填充剩余高度
- `option.add.enable` → 启用新增按钮
- `option.delete.enable` → 启用删除（支持函数动态判断）
- `option.delete.before(rows)` → 删除前校验（return false 阻止）
- `option.edit.enable` → 启用编辑（支持函数动态判断）
- `option.view.enable` → 启用查看
- `option.search.query` → 查询 API 方法
- `option.export.enable` → 启用导出
- `option.export.method` → 导出 API 方法

### 国际化 ($t)
- `$t('key||中文默认值')` → 带默认值的国际化
- `$t('table.entityName.fieldName||字段中文名')` → 表格字段
- `$t('operate||操作')`, `$t('add||新增')`, `$t('edit||编辑')`
- `$t('submit||提交')`, `$t('submit.success||提交成功')`
- `$t('error.input.notEmpty||输入不能为空')`

---

## MyBatis-Plus 拦截器链

按执行顺序:
1. `TenantLineInnerInterceptor` — 多租户 org_id 自动注入
2. `AdvanceQueryInterceptor` — 高级查询（Oracle）
3. `PaginationInnerInterceptor` — 分页（overflow 已启用）
4. `OptimisticLockerInnerInterceptor` — 乐观锁（@Version 字段）
5. `BatchUpdateInterceptor` — 批量更新
6. `AuditLogInterceptor` — 审计日志

---

## 全局注册组件

通过 `Vue.component()` 全局注册，可直接使用:
- `tw-table` — 核心表格组件
- `master-sub` — 主子表布局（垂直分栏）
- `tw-card` — 卡片容器
- `RemoteSelect` — 远程下拉选择
- `RemoteCheckbox` — 远程复选框
- `RemoteRadio` — 远程单选框
- `TableSelect` — 表格弹窗选择（放大镜）
- `SelectModal` — 选择弹窗
