|
|
|
@ -371,6 +371,137 @@ mock/*.ts 文件内容来源:
|
|
|
|
- 大屏看板:独立深色主题(#0f0f1a背景/#1a1a2e卡片),样式文件 `styles/screen.scss`
|
|
|
|
- 大屏看板:独立深色主题(#0f0f1a背景/#1a1a2e卡片),样式文件 `styles/screen.scss`
|
|
|
|
- 不引入Tailwind CSS
|
|
|
|
- 不引入Tailwind CSS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Mock→API切换 Checklist(强制)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
联调切换时,开发者必须执行以下检查清单,逐项确认后才能声明切换完成:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. **全局搜索残留**:
|
|
|
|
|
|
|
|
- 搜索代码中所有 `mock-api` 字符串,确认零残留
|
|
|
|
|
|
|
|
- 搜索所有 `/mock-api/` URL 引用,确认零残留
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2. **逐调用点确认URL**:
|
|
|
|
|
|
|
|
- 搜索所有 `request.get(`、`request.post(`、`request.put(`、`request.delete(` 调用点
|
|
|
|
|
|
|
|
- 输出完整清单(文件路径 + 行号 + URL)
|
|
|
|
|
|
|
|
- 逐个确认每个 URL 已从 Mock 风格切换为 RESTful 风格
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3. **逐调用点确认HTTP方法**:
|
|
|
|
|
|
|
|
- 写操作(新增/编辑/删除/启停)必须使用正确的 RESTful 方法(POST/PUT/DELETE)
|
|
|
|
|
|
|
|
- 禁止写操作用 GET
|
|
|
|
|
|
|
|
- 禁止所有操作都用 POST(Mock 遗留)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4. **对照API设计文档**:
|
|
|
|
|
|
|
|
- 打开 `docs/03-API接口设计.md` 的正式API列
|
|
|
|
|
|
|
|
- 逐个端点确认前端调用 URL 和 Method 与文档一致
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**检查模板:**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
模块:设备管理
|
|
|
|
|
|
|
|
切换日期:2026-04-XX
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| # | 前端方法 | 文件 | Mock URL | 正式 URL | HTTP Method | 已确认 |
|
|
|
|
|
|
|
|
|---|---------|------|---------|---------|-------------|--------|
|
|
|
|
|
|
|
|
| 1 | loadData | MachineListPage.vue | POST /mock-api/machine/list | GET /api/admin/machine | GET | ✅ |
|
|
|
|
|
|
|
|
| 2 | handleCreate | MachineListPage.vue | POST /mock-api/machine/create | POST /api/admin/machine | POST | ✅ |
|
|
|
|
|
|
|
|
| 3 | handleEdit | MachineListPage.vue | POST /mock-api/machine/update | PUT /api/admin/machine/{id} | PUT | ✅ |
|
|
|
|
|
|
|
|
| ... | ... | ... | ... | ... | ... | ... |
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### RESTful 调用规范
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. **资源 ID 必须使用路径参数传递**:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
|
|
// ✅ 正确:ID 在 URL 路径中
|
|
|
|
|
|
|
|
request.get(`/api/admin/machine/${id}/status`)
|
|
|
|
|
|
|
|
request.put(`/api/admin/machine/${id}/toggle`)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ❌ 错误:ID 在 query 参数中
|
|
|
|
|
|
|
|
request.get('/api/admin/machine/status', { params: { id } })
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2. **禁止自行编造后端不存在的接口**:
|
|
|
|
|
|
|
|
- 前端调用的每个 URL 必须在 `docs/03-API接口设计.md` 的正式API列中存在
|
|
|
|
|
|
|
|
- 批量操作如果后端只提供单个操作接口,前端通过循环调用实现,不编造批量端点
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3. **代码审查必检项**:
|
|
|
|
|
|
|
|
- 每个新增的 `request.xxx()` 调用,审查时必须对照 API 设计文档确认 URL 和 Method 正确
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### el-pagination 使用规范
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
使用 `<el-pagination>` 组件时,**必须同时**绑定以下事件:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
|
|
|
<!-- ✅ 正确:v-model + 事件绑定 -->
|
|
|
|
|
|
|
|
<el-pagination
|
|
|
|
|
|
|
|
v-model:current-page="query.page"
|
|
|
|
|
|
|
|
v-model:page-size="query.pageSize"
|
|
|
|
|
|
|
|
:page-sizes="[20, 50, 100]"
|
|
|
|
|
|
|
|
:total="total"
|
|
|
|
|
|
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
|
|
|
|
@current-change="loadData"
|
|
|
|
|
|
|
|
@size-change="handleSizeChange"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
|
|
const handleSizeChange = () => {
|
|
|
|
|
|
|
|
query.page = 1 // 切换每页条数时回到第1页
|
|
|
|
|
|
|
|
loadData()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
|
|
|
<!-- ❌ 错误:只有 v-model,没有事件绑定 -->
|
|
|
|
|
|
|
|
<!-- v-model 只更新响应式变量的值,不会自动触发数据加载 -->
|
|
|
|
|
|
|
|
<el-pagination
|
|
|
|
|
|
|
|
v-model:current-page="query.page"
|
|
|
|
|
|
|
|
v-model:page-size="query.pageSize"
|
|
|
|
|
|
|
|
:total="total"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**原因**:`v-model:current-page` 只是双向绑定数据,页码变化时不会自动调用 `loadData()`。必须通过 `@current-change` 和 `@size-change` 事件手动触发数据请求。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 布尔字段类型规范
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. **TypeScript 接口中二元状态字段使用 `boolean` 类型**:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
|
|
// ✅ 正确
|
|
|
|
|
|
|
|
interface Machine {
|
|
|
|
|
|
|
|
isOnline: boolean
|
|
|
|
|
|
|
|
isEnabled: boolean
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ❌ 错误
|
|
|
|
|
|
|
|
interface Machine {
|
|
|
|
|
|
|
|
isOnline: number // 0/1 语义不明确
|
|
|
|
|
|
|
|
isEnabled: number // 隐式转换碰巧正确但不可靠
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2. **后端返回 `int` 时的前端处理**:如果后端 DTO 暂时无法改为 `bool`(需协调),前端应在 API 响应拦截或数据转换层统一转为 `boolean`:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
|
|
|
// 在 loadData 或 API 响应处理中
|
|
|
|
|
|
|
|
const machine = {
|
|
|
|
|
|
|
|
...raw,
|
|
|
|
|
|
|
|
isOnline: Boolean(raw.isOnline),
|
|
|
|
|
|
|
|
isEnabled: Boolean(raw.isEnabled),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3. **禁止在模板中使用 number 做隐式布尔判断**:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
|
|
|
<!-- ❌ 错误:number 隐式转换 -->
|
|
|
|
|
|
|
|
<el-tag :type="detail.isOnline ? 'success' : 'info'">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ✅ 正确:boolean 显式判断 -->
|
|
|
|
|
|
|
|
<el-tag :type="detail.isOnline ? 'success' : 'info'">
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 大屏独立规范
|
|
|
|
### 大屏独立规范
|
|
|
|
|
|
|
|
|
|
|
|
- 独立Layout:`ScreenLayout.vue`(全屏,无侧边栏/面包屑)
|
|
|
|
- 独立Layout:`ScreenLayout.vue`(全屏,无侧边栏/面包屑)
|
|
|
|
|