7.2 KiB
| name | description |
|---|---|
| jjb-declare-request | 定义 JJB 接口定义规范。在使用 declareRequest、Action 命名、Loading 状态或 resetModelState 时使用。必须参考 MD/d.ts 文档。 |
接口与数据层规范
接口定义规范 (declareRequest)
所有接口必须通过 declareRequest 进行声明。该方法通过字符串 DSL 实现请求配置与数据处理。
必须严格参考对应 MD 文档或 d.ts 文件!
基本语法
declareRequest(
a?: string, // 参数1:Loading 状态标识(可选)
b: string, // 参数2:请求表达式(必填)
c?: string // 参数3:响应数据处理表达式(可选)
)
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| a | string | 否 | 请求时绑定的 Loading 状态标识,例如 "loading"、"confirmLoading" |
| b | string | 是 | 请求表达式,格式:Method [> @] URL,支持完整 http[s] 路径 |
| c | string | 否 | 响应数据处理表达式,用于从响应结果中取值并赋给目标字段 |
定义示例
import { declareRequest } from '@cqsjjb/jjb-dva-runtime';
// 示例1:获取试卷列表(完整参数)
export const getExamResDataAction = declareRequest(
'examResDataLoading', // 参数1:Loading 状态字段名
'Get > /com-train/exams', // 参数2:请求方法 > 接口路径
'examResData: [] | res.data || [] & examResDataTotal: 0 | res.totalCount || 0' // 参数3:数据映射与默认值
);
// 示例2:仅定义请求(省略参数1和参数3)
export const getUserInfoAction = declareRequest(
'Get > /api/user/{id}' // 仅必填参数
);
// 示例3:POST 请求使用 @ 标记
export const createUserAction = declareRequest(
'createUserLoading',
'Post > @/api/user', // @ 标记忽略 request 包裹层
'userId: "" | res.data.id || ""'
);
命名格式
[name]Action 统一使用 小驼峰 (camelCase) 命名
⚠️ 禁止使用的关键字
禁止使用以下关键字作为 Action 名称,这些是 Connect 装饰器注入的保留字段和方法,使用会导致冲突异常:
dispatch:Dva dispatch 方法resetModelState:重置模型状态方法dispatchModelAction:手动调用 Action 方法getModelState:获取模型状态方法props:命名空间对应的 props 对象models:所有连接的模型对象action:通用 Action 标识(避免冲突)
❌ 错误示例
import { declareRequest } from '@cqsjjb/jjb-dva-runtime';
// ❌ 错误:使用了保留关键字
export const dispatch = declareRequest('Get > /api/user');
export const resetModelState = declareRequest('Get > /api/user');
export const dispatchModelAction = declareRequest('Get > /api/user');
export const getModelState = declareRequest('Get > /api/user');
export const props = declareRequest('Get > /api/user');
export const models = declareRequest('Get > /api/user');
export const action = declareRequest('Get > /api/user');
✅ 正确示例
import { declareRequest } from '@cqsjjb/jjb-dva-runtime';
// ✅ 正确:使用符合规范的命名
export const fetchUserAction = declareRequest('Get > /api/user');
export const getUserListAction = declareRequest('Get > /api/users');
export const createUserAction = declareRequest('Post > @/api/user');
export const updateUserAction = declareRequest('Put > @/api/user/{id}');
请求表达式规范
-
格式:
Method [> @] URL -
支持的 HTTP 方法:
Get:GET 请求Post:POST 请求Put:PUT 请求Delete:DELETE 请求Patch:PATCH 请求
-
@ 标记说明:
-
作用:忽略请求体中
request对象的包裹层,直接传递数据 -
限制:Get 请求不能使用 @,其他请求方法可选
-
示例:
// ✅ POST 请求使用 @,忽略 request 包裹 'Post > @/api/user' // ❌ GET 请求禁止使用 @ 'Get > @/api/user/{id}' // 错误写法
-
-
URL 路径规范:
-
普通路径:例如
/api/xxx/list -
模板插值:支持占位符
{},调用时会替换为参数值// 示例:URL 模板插值 'Get > /api/user/{id}' // 调用时 {id} 会被替换为实际参数值 -
完整 HTTP 路径:支持完整的 http[s] 路径
-
请求格式限制:仅支持
application/json格式,其他格式不支持
-
响应表达式规范
-
格式:
targetField: defaultValue | expression & ... -
组成部分:
-
targetField:目标字段名称 -
defaultValue:当结果为空时的默认值 -
expression:从响应对象中获取数据的 JS 表达式 -
&:支持多个字段连接 -
res:固定上下文对象,表示响应结果
-
-
示例:
// 示例:多字段映射 'dataSource: [] | res.data || [] & total: 0 | res.total || 0'表示:
-
将结果赋值给
dataSource,默认值为[],优先取res.data,如果为空则取[] -
&连接下一个字段 -
将结果赋值给
total,默认值为0,优先取res.total,如果为空则取0
-
-
AI 约束:必须根据后端返回结构精确配置此映射
使用规则总结
-
@ 标记限制:Get 请求不能用
@,其他请求方法可选 -
URL 模板插值:支持路径模板插值
{id},调用时自动替换 -
参数可选性:参数 a(Loading 状态)、c(响应处理)可选,不写也能正常工作
-
请求格式:仅支持
application/json格式
Loading 状态管理规范
⚠️ 重要约束:当
declareRequest定义的接口 Action 在弹窗、抽屉等可关闭组件中使用时,必须在组件销毁时调用resetModelState重置对应的 loading 字段。
问题说明
declareRequest 定义的接口 Action 会自动管理 loading 状态(如 loading、confirmLoading、submitLoading 等)。但在以下场景中,loading 状态可能无法自动重置:
- 接口请求异常中断
- 弹窗/抽屉在请求过程中被关闭
- 组件卸载时请求仍在进行
这会导致 loading 状态一直保持为 true,下次打开组件时仍然显示加载状态,影响用户体验。
解决方案
在组件销毁时(如弹窗的 onCancel、afterClose 或 useEffect 清理函数),调用 resetModelState 重置对应的 loading 字段。
示例
import { useEffect } from 'react';
import { Connect } from '@cqsjjb/jjb-dva-runtime';
import { NS_USER } from '~/enumerate/namespace';
function UserModal({ createUserAction, resetModelState, modalOpen }) {
useEffect(() => {
if (!modalOpen) {
// ✅ 弹窗关闭时重置 loading 状态
resetModelState(NS_USER, { confirmLoading: false });
}
}, [modalOpen]);
// ... 其他代码
}
export default Connect([NS_USER], true)(UserModal);
相关规范
- 关于 loading 状态重置的详细说明和多种场景示例,请参考
Loading状态重置规范 - 关于
resetModelState的详细用法,请参考命名空间与视图连接