init: 初始化 hgmj 后台管理项目

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 17:48:09 +08:00
co-authored by Claude Opus 4.7
commit 397398b746
645 changed files with 179153 additions and 0 deletions
@@ -0,0 +1,63 @@
---
name: vue2-api-integration
description: Use when implementing or debugging API integration in this Vue2 project, including request parameter mapping, response normalization, business error handling, auth expiry handling, and submit/list flow consistency.
disable-model-invocation: true
---
# Vue2 API Integration
## 适用场景
- 新增或修改 `src/api/*.js` 接口方法
- 页面查询、提交、删除、状态切换的接口联调
- 线上/测试环境出现接口报错、数据格式不一致、权限失效
## 联调核心原则
- **一处定义接口**:请求方法统一维护在 `src/api`,页面层不写裸请求
- **参数先整形再发送**:空值、时间范围、布尔值、数字类型先归一化
- **响应做兜底**:列表、分页、详情都要有默认值,避免空指针
- **错误统一反馈**:用户看得懂、可操作;开发可定位
- **鉴权失效可恢复**:401/403 走统一处理,避免页面卡死
## 请求层约定
- GET 查询使用 `params`,POST/PUT 使用 `data`
- 接口函数命名表达业务动作:`getXxxList`、`createXxx`、`updateXxx`
- 同类接口保持参数结构一致,降低页面层分支逻辑
## 页面层约定
- 页面只做调用、状态切换、提示和数据映射
- 所有异步方法都要有 `loading` 生命周期(开始/结束)
- 提交类动作默认防重复:`submitLoading` 或按钮禁用
- 删除/危险操作必须确认后调用
## 常见数据映射
- 时间区间:`[startTime, endTime]` 拆成后端需要字段
- 开关状态:`true/false` 映射为后端约定值(如 `1/0`)
- 数字输入:提交前转数字,避免 `"1"`/`1` 混用
- 列表响应:`list`、`total` 必须有默认值
## 错误与鉴权处理
- 业务失败:提示明确失败原因,不吞错误
- 网络异常:提示“网络异常,请稍后重试”
- 401:提示登录失效并引导重新登录
- 403:提示无权限并保持当前页面可回退
- 异常分支必须收尾:关闭 loading、恢复按钮状态
## 推荐联调流程
1. 先确认接口文档字段和返回结构
2. 在 `src/api` 定义/更新请求函数
3. 页面接入并补齐参数整形与响应兜底
4. 跑通成功路径(查询/提交)
5. 验证失败路径(业务报错/网络异常/无权限)
6. 执行 lint 或 test-build 确认无新增阻断问题
## 快速参考
- 示例代码:见 [examples.md](examples.md)
- 联调检查表:见 [checklist.md](checklist.md)
@@ -0,0 +1,30 @@
# Checklist
## 接口定义检查
- [ ] 接口方法统一定义在 `src/api/*.js`
- [ ] GET 使用 `params`,POST/PUT 使用 `data`
- [ ] 方法名与业务动作匹配(get/create/update/delete)
- [ ] 请求路径、method、参数字段与后端约定一致
## 页面联调检查
- [ ] 查询参数已整形(时间范围、布尔、数字、空值)
- [ ] 列表响应有默认值(`list`、`total`)
- [ ] 提交按钮有防重复(`submitLoading`/禁用)
- [ ] 删除/危险动作有二次确认
- [ ] 异常场景会关闭 loading 并提示用户
## 错误与权限检查
- [ ] 业务错误提示清晰,不吞异常
- [ ] 网络异常提示可理解(可重试)
- [ ] 401 有登录失效处理
- [ ] 403 有无权限处理与回退路径
## 交付前检查
- [ ] 成功路径通过(查询/提交/删除)
- [ ] 失败路径通过(业务失败/网络异常/权限失败)
- [ ] 执行 `npm run lint` 或 `npm run test-build`
- [ ] 不提交无关改动
@@ -0,0 +1,78 @@
# Examples
## API 方法定义示例
```js
import request from "@/utils/request";
export function getCheckInList(params) {
return request({
url: "/signin/checkin/list",
method: "get",
params
});
}
export function saveCheckInConfig(data) {
return request({
url: "/signin/checkin/config/save",
method: "post",
data
});
}
```
## 查询参数整形示例
```js
buildQueryParams() {
const { dateRange, status, pageNum, pageSize, keyword } = this.queryForm;
return {
pageNum,
pageSize,
keyword: keyword ? keyword.trim() : "",
status: typeof status === "boolean" ? (status ? 1 : 0) : status,
startTime: dateRange && dateRange.length ? dateRange[0] : "",
endTime: dateRange && dateRange.length ? dateRange[1] : ""
};
}
```
## 列表请求与兜底示例
```js
async fetchList() {
this.loading = true;
try {
const params = this.buildQueryParams();
const res = await getCheckInList(params);
const data = (res && res.data) || {};
this.tableData = Array.isArray(data.list) ? data.list : [];
this.total = Number(data.total || 0);
} catch (e) {
this.$message.error("列表加载失败,请稍后重试");
} finally {
this.loading = false;
}
}
```
## 提交流程与防重复示例
```js
async handleSubmit() {
if (this.submitLoading) return;
this.submitLoading = true;
try {
await this.$refs.formRef.validate();
await saveCheckInConfig(this.formData);
this.$message.success("保存成功");
this.dialogVisible = false;
this.fetchList();
} catch (e) {
this.$message.error("保存失败,请检查后重试");
} finally {
this.submitLoading = false;
}
}
```