feat: 更新接口

This commit is contained in:
tsl 2026-04-16 10:30:18 +08:00
parent 82c2b0f1bd
commit 8137d414da
4 changed files with 430 additions and 100 deletions

View File

@ -1,27 +1,32 @@
# API 开发与类型定义流程 # API 开发与类型定义流程
为了保持代码健壮性,新增接口时请遵循以下步骤 当前接口与类型定义以 OpenAPI 文档为准
## 1. 记录请求与响应 (data/api/) - 源文件:`data/api/默认模块.openapi.json`
- 来源:该文件由 **Apifox 导出**
- 内容:包含接口定义、字段说明、请求/响应示例
- **分文件夹管理**:每个接口在 `data/api/` 下拥有独立文件夹。 ## 1. 更新 OpenAPI 文档
- **请求逻辑 (`request.ts`)**:使用 Axios 编写接口调用逻辑,调用 `saveResponse(__dirname, data)` 自动保存响应。
- **响应数据 (`response.json`)**:运行 `npx tsx data/api/run.ts` 后,会在该接口文件夹下生成或更新真实数据。
- **自动化工具**:一键同步所有接口数据:
```bash - 在 Apifox 中维护接口后,导出最新 OpenAPI 文件并覆盖 `data/api/默认模块.openapi.json`
npx tsx data/api/run.ts - 新增/修改接口时先以该文件为唯一事实来源Single Source of Truth
```
## 2. 定义类型 (src/types/api.ts) ## 2. 生成/更新接口层 (src/api/)
- 根据生成的 `response.json` 数据结构,在 `src/types/api.ts` 中创建接口 - 根据 `paths` 中的接口定义,更新 `src/api/` 下的请求函数(路径、方法、请求参数)
- **规则**:新增成员变量时务必添加 JSDoc 注释 - 保持现有业务兼容时,可新增标准方法并保留旧方法别名
## 3. 注册 URL (src/constants/api.ts) ## 3. 生成/更新类型定义 (src/api/types/)
- 在 `API_BASE` 基础上定义新的常量。 - 根据 OpenAPI 中的 schema、字段说明和示例维护 `src/api/types/` 下类型。
- 在 `src/api/types/index.ts` 统一导出类型。
- 新增字段时补充必要注释,命名与接口字段保持一致。
## 4. 业务调用 ## 4. 使用与校验
- 在对应的 Pinia Store 中使用 `ApiResponse<T>` 包装请求返回值。 - 在业务层使用 `ApiResponse<T>` 包装响应类型。
- 修改后执行类型检查:
```bash
npm run type-check
```

View File

@ -1,11 +1,72 @@
import { post, requestRaw } from "@/api/client"; import { post, requestRaw } from "@/api/client";
import type { import type {
LoginResponseData,
WorkOrderResponseData,
CheckStatusResponse,
ApiResponse, ApiResponse,
CheckStatusResponse,
DemandItem,
DemandListPageRequest,
DemandListPageResponseData,
DemandListRequest,
LoginResponseData,
LoginRequest,
ProductItem,
ProjectItem,
ProjectListRequest,
QueryIndexCountRequest,
SystemUserItem,
WorkOrderListPageRequest,
WorkOrderResponseData,
} from "@/api/types"; } from "@/api/types";
const defaultWorkOrderListPageRequest: WorkOrderListPageRequest = {
DL_ProductID: 64,
DL_ID: "",
isSelect: 0,
Solution: "",
OrderType: "",
DL_TaskName: "",
CreatGID: "",
CreatTimeStart: "",
CreatTimeEnd: "",
SloveGID: "",
SloveTimeStart: "",
SloveTimeEnd: "",
ShowTable: "DemandList",
isShow: 3,
IsExport: 0,
PageIndex: 1,
PageSize: 20,
};
const defaultDemandListPageRequest: DemandListPageRequest = {
PageIndex: 1,
PageSize: 10000,
DL_TaskName: null,
DL_ProductID: 64,
ShowTable: "AuditList",
isShow: 2,
isSelect: 6,
OrderType: 0,
WAffGID: "",
DL_Status: "",
};
const defaultDemandListRequest: DemandListRequest = {
DL_AssignName: 1,
};
const defaultProjectListRequest: ProjectListRequest = {
PD_GID: "",
NOClose: "",
};
function withSessionCookie(sessionId: string) {
return {
headers: {
Cookie: `ASP.NET_SessionId=${sessionId}`,
},
};
}
/** /**
* *
* @param account * @param account
@ -17,7 +78,7 @@ export async function login(
password: string, password: string,
): Promise<{ data: ApiResponse<LoginResponseData>; sessionId: string }> { ): Promise<{ data: ApiResponse<LoginResponseData>; sessionId: string }> {
// 登录接口需要特殊处理,因为需要从响应头中获取 sessionId // 登录接口需要特殊处理,因为需要从响应头中获取 sessionId
const loginData = { const loginData: LoginRequest = {
Account: account, Account: account,
PassWord: password, PassWord: password,
}; };
@ -48,35 +109,102 @@ export async function login(
} }
/** /**
* * GetWorkOrderListPage
* @param sessionId ID * @param sessionId ID
* @returns * @param payload 使 OpenAPI
* @returns
*/
export async function getWorkOrderListPage(
sessionId: string,
payload: WorkOrderListPageRequest = {},
): Promise<ApiResponse<WorkOrderResponseData>> {
const requestData: WorkOrderListPageRequest = {
...defaultWorkOrderListPageRequest,
...payload,
};
return post<ApiResponse<WorkOrderResponseData>, WorkOrderListPageRequest>(
"/DemandManage/GetWorkOrderListPage",
requestData,
withSessionCookie(sessionId),
);
}
/**
*
* @param sessionId ID
* @returns
*/ */
export async function checkWorkOrders( export async function checkWorkOrders(
sessionId: string, sessionId: string,
): Promise<ApiResponse<WorkOrderResponseData>> { ): Promise<ApiResponse<WorkOrderResponseData>> {
// 请求数据类型 return getWorkOrderListPage(sessionId, {
const requestData = {
isSelect: 8, isSelect: 8,
isShow: 3, isShow: 3,
IsExport: 0, IsExport: 0,
PageIndex: 1, PageIndex: 1,
PageSize: 20, PageSize: 20,
});
}
/**
* GetDemandListPage
* @param sessionId ID
* @param payload 使 OpenAPI
* @returns
*/
export async function getDemandListPage(
sessionId: string,
payload: DemandListPageRequest = {},
): Promise<ApiResponse<DemandListPageResponseData>> {
const requestData: DemandListPageRequest = {
...defaultDemandListPageRequest,
...payload,
}; };
return post<ApiResponse<WorkOrderResponseData>, typeof requestData>( return post<ApiResponse<DemandListPageResponseData>, DemandListPageRequest>(
"/DemandManage/GetWorkOrderListPage", "/DemandManage/GetDemandListPage",
requestData, requestData,
{ withSessionCookie(sessionId),
headers: {
Cookie: `ASP.NET_SessionId=${sessionId}`,
},
},
); );
} }
/** /**
* * GetDemandList
* @param sessionId ID
* @param payload
* @returns
*/
export async function getDemandList(
sessionId: string,
payload: DemandListRequest = defaultDemandListRequest,
): Promise<ApiResponse<DemandItem[]>> {
return post<ApiResponse<DemandItem[]>, DemandListRequest>(
"/DemandManage/GetDemandList",
payload,
withSessionCookie(sessionId),
);
}
/**
* QueryIndexCount
* @param sessionId ID
* @param payload
* @returns
*/
export async function queryIndexCount(
sessionId: string,
payload: QueryIndexCountRequest = {},
): Promise<ApiResponse<CheckStatusResponse>> {
return post<ApiResponse<CheckStatusResponse>, QueryIndexCountRequest>(
"/DemandManage/QueryIndexCount",
payload,
withSessionCookie(sessionId),
);
}
/**
*
* @param sessionId ID * @param sessionId ID
* @param userGid GID * @param userGid GID
* @returns * @returns
@ -85,17 +213,54 @@ export async function checkStatus(
sessionId: string, sessionId: string,
userGid?: string, userGid?: string,
): Promise<ApiResponse<CheckStatusResponse>> { ): Promise<ApiResponse<CheckStatusResponse>> {
// 请求数据类型 return queryIndexCount(sessionId, userGid ? { UserGID: userGid } : {});
const requestData: Record<string, string> = {}; }
if (userGid) requestData.UserGID = userGid;
return post<ApiResponse<CheckStatusResponse>, typeof requestData>( /**
"/DemandManage/QueryIndexCount", * GetSystemUser
requestData, * @param sessionId ID
{ */
headers: { export async function getSystemUserList(
Cookie: `ASP.NET_SessionId=${sessionId}`, sessionId: string,
}, ): Promise<ApiResponse<SystemUserItem[]>> {
}, return post<ApiResponse<SystemUserItem[]>, Record<string, never>>(
"/SystemUser/GetSystemUser",
{},
withSessionCookie(sessionId),
);
}
/**
* GetProductMange
* @param sessionId ID
*/
export async function getProductList(
sessionId: string,
): Promise<ApiResponse<ProductItem[]>> {
return post<ApiResponse<ProductItem[]>, Record<string, never>>(
"/ProductManage/GetProductMange",
{},
withSessionCookie(sessionId),
);
}
/**
* GetProject
* @param sessionId ID
* @param payload
*/
export async function getProjectList(
sessionId: string,
payload: ProjectListRequest = {},
): Promise<ApiResponse<ProjectItem[]>> {
const requestData: ProjectListRequest = {
...defaultProjectListRequest,
...payload,
};
return post<ApiResponse<ProjectItem[]>, ProjectListRequest>(
"/ProjectMange/GetProject",
requestData,
withSessionCookie(sessionId),
); );
} }

View File

@ -1,6 +1,7 @@
/** 通用 API 响应 */ /** 通用 API 响应 */
export interface ApiResponse<T = unknown> { export interface ApiResponse<T = unknown> {
success: boolean; success: boolean;
code?: string | null;
msg: string; msg: string;
data: T; data: T;
} }

View File

@ -1,57 +1,134 @@
/** 菜单信息 */ /** 菜单信息 */
export interface MenuInfo { export interface MenuInfo {
/** 唯一标识 */
GID: string; GID: string;
/** 菜单名称 */
MM_Name: string; MM_Name: string;
/** 链接地址 */
MM_LinkUrl: string; MM_LinkUrl: string;
/** 父级 ID */
MM_ParentID: string; MM_ParentID: string;
/** 排序 */
MM_Sort: number; MM_Sort: number;
/** 备注/标记 */
MM_Mark: string | null; MM_Mark: string | null;
/** 图标 */
MM_Ico: string; MM_Ico: string;
/** 资源列表 */
ResourceList: unknown; ResourceList: unknown;
} }
/** 角色资源权限 */ /** 角色资源权限 */
export interface SRRoleItem { export interface SRRoleItem {
/** 唯一标识 */
GID: string; GID: string;
/** 菜单 GID */
MM_GID: string; MM_GID: string;
/** 资源名称 */
RS_Name: string; RS_Name: string;
/** 资源链接 */
RS_LinkUrl: string; RS_LinkUrl: string;
/** 是否显示 */
RS_IsShow: number; RS_IsShow: number;
/** 排序 */
RS_Sort: number; RS_Sort: number;
/** 创建时间 */
RS_CreateTime: string; RS_CreateTime: string;
/** 资源编码 */
RS_Code: string | null; RS_Code: string | null;
} }
/** 登录 API 响应中的 data 部分 */ /** 系统用户信息(登录与用户列表共用) */
export interface LoginResponseData { export interface SystemUserInfo {
/** 用户唯一标识 GID */
GID: string; GID: string;
/** 用户名 */ SR_GID: string;
SU_UserName: string; SD_GID: string;
/** 账号/工号 */
SU_Account: string; SU_Account: string;
/** 角色名称 */ SU_Password: string;
SR_Name: string; SU_AdminType: number;
/** 菜单列表 */ SU_IsDisable: number;
MenuInfoList?: MenuInfo[]; SU_UserName: string;
/** 角色权限列表 */ SU_Telephone: string;
SRRole?: SRRoleItem[]; SU_LastLoginTime: string | null;
SU_CreateTime: string;
SU_Creator: string | null;
SU_Flag: string | null;
SU_Code: string;
SU_BrowseRole: number;
SU_QQCode: string;
SU_WeChatImageUrl: string | null;
SU_IsShunt: number;
MaxReception: number;
AG_GID: string;
SU_WeChatCode: string | null;
SU_UserType: number;
SR_Name: string | null;
SD_Name: string | null;
AG_Domain: string | null;
AG_Type: number;
AG_SoftwareName: string | null;
AG_Contacter: string | null;
DL_CreatNum: number | null;
DL_SloveNum: number | null;
BUGNum: number | null;
DMNum: number | null;
TESNum: number | null;
ACNum: number | null;
WorkHour: string | number | null;
WaitCloseNum: number | null;
CloseNum: number | null;
SRRole: SRRoleItem[] | null;
MenuInfoList: MenuInfo[] | null;
}
/** 登录接口返回的用户信息 */
export type LoginResponseData = SystemUserInfo;
/** 系统用户列表项 */
export type SystemUserItem = SystemUserInfo;
/** 登录请求参数 */
export interface LoginRequest {
UserAcount?: null;
PassWord: string;
VerifyCode?: null;
Account: string;
ValidateCode?: null;
}
/** 工单分页查询参数 */
export interface WorkOrderListPageRequest {
DL_ProductID?: number;
DL_ID?: string;
isSelect?: number;
Solution?: string;
OrderType?: string;
DL_TaskName?: string;
CreatGID?: string;
CreatTimeStart?: string;
CreatTimeEnd?: string;
SloveGID?: string;
SloveTimeStart?: string;
SloveTimeEnd?: string;
ShowTable?: string;
isShow?: number;
IsExport?: number;
PageIndex?: number;
PageSize?: number;
}
/** 审核工单分页查询参数 */
export interface DemandListPageRequest {
PageIndex?: number;
PageSize?: number;
DL_TaskName?: string | null;
DL_ProductID?: number;
ShowTable?: string;
isShow?: number;
isSelect?: number;
OrderType?: number;
WAffGID?: string;
DL_Status?: string;
}
/** 我的地盘查询参数 */
export interface DemandListRequest {
DL_AssignName?: number;
}
/** 待处理数据概览查询参数 */
export interface QueryIndexCountRequest {
UserGID?: string;
}
/** 项目列表查询参数 */
export interface ProjectListRequest {
PD_GID?: string;
NOClose?: string;
} }
/** 检查状态接口返回的计数数据 */ /** 检查状态接口返回的计数数据 */
@ -61,44 +138,126 @@ export interface CheckStatusResponse {
ConfirmCount?: number; ConfirmCount?: number;
} }
/** 工单列表项 */ /** 工单明细(用于工单列表/审核列表/我的地盘) */
export interface WorkOrderItem { export interface DemandItem {
/** 工单 ID */
ID: number; ID: number;
/** 需求名称/标题 */ DL_OrderType: number;
DL_DemandName: string;
/** 需求内容 */
DL_DemandContent: string;
/** 创建人 */
DL_Creator: string;
/** 创建时间 */
DL_CreateTime: string;
/** 状态码 (如 350) */
DL_Status: number; DL_Status: number;
/** 优先级 */ DL_StatusID: number | null;
DL_Priority: string; DL_ProductID: number;
/** 产品名称 */
DL_ProductName: string; DL_ProductName: string;
/** 指派人 */ DL_ID: number | null;
DL_AssignName: string | null; DL_ItemID: string | null;
/** 关联项目 ID */ DL_ProblemDegree: string;
DL_ID: number; DL_Priority: string | null;
/** 关联项目名称 */ DL_TaskName: string;
DL_ItemID: string; DL_ProblemSource: string;
DL_CreatorGID: string;
DL_Creator: string;
DL_CreateTime: string;
DL_AffirmGID: string | null;
DL_AffirmName: string | null;
DL_ConfirmTime: string | null;
DL_AffirmRemark: string | null;
DL_AssignGID: string;
DL_AssignName: string;
DL_AssignRemark: string | null;
DL_SolveGID: string | null;
DL_SolveName: string | null;
DL_SolveTime: string | null;
DL_SolveRemark: string | null;
DL_CloseGID: string | null;
DL_CloseName: string | null;
DL_CloseTime: string | null;
DL_CloseRemark: string | null;
DL_Remark: string | null;
DL_AuditStatus: number | string | null;
DL_DemandContent: string;
DL_TestContent: string;
DL_DemandName: string;
DL_OrderLevel: number;
DL_RepeatID: number | null;
DL_RepeatStatus: number | null;
DL_Identitying: number | null;
DL_WorkHour: string | number | null;
DL_ConfirmState: number | null;
} }
/** 工单查询接口返回的 data 部分 */ /** 兼容旧命名 */
export interface WorkOrderResponseData { export type WorkOrderItem = DemandItem;
/** 总页数 */
/** 分页工单数据 */
export interface DemandPageData {
PageTotal: number; PageTotal: number;
/** 每页数量 */
PageSize: number; PageSize: number;
/** 总数 */
DataCount: number; DataCount: number;
/** 当前页码 */
PageIndex: number; PageIndex: number;
/** 工单列表 */ DataList: DemandItem[];
DataList: WorkOrderItem[]; StatisticsInfo: unknown | null;
TrendData: unknown | null;
}
/** 兼容旧命名 */
export type WorkOrderResponseData = DemandPageData;
/** 审核工单分页响应数据 */
export type DemandListPageResponseData = DemandPageData;
/** 产品列表项 */
export interface ProductItem {
ID: number;
PM_ProductName: string;
PM_ProductID: string;
PM_ProductLeader: string;
PM_ProductGID: string | null;
PM_TestLeader: string;
PM_TestGID: string | null;
PM_PublishLeader: string;
PM_PublishGID: string | null;
PM_Creator: string;
PM_CreateTime: string;
PM_Remark: string | null;
}
/** 项目列表项 */
export interface ProjectItem {
PJ_TestedBy: string | null;
ID: number;
PJ_Name: string | null;
PJ_Code: string;
PJ_Product: string;
PD_GID: string;
PJ_Principal: string | null;
PJ_Receiver: string | null;
SU_GID: string | null;
PJ_State: string;
PJ_PredictReleaseTime: string;
PJ_Actual: string;
PJ_ActualEndTime: string;
PJ_Creator: string;
PJ_CreatTime: string;
PJ_Remark: string | null;
PJ_PredictStartTime: string | null;
PJ_BUGStatistics: number;
PJ_DemandStatistics: number;
PJ_TestStatistics: number;
PJ_WorkHourstics: string;
PJ_ActivaStatistics: number;
PJ_ReceiverStatistics: number;
PJ_ContentDescribe: string | null;
BUGNum: number | null;
DMNum: number | null;
TESNum: number | null;
ACNum: number | null;
WorkHour: string | number | null;
ReceiverNum: number | null;
PJ_Participants: string | null;
PJ_ResultFeedback: string | null;
PJ_ActualStartTime: string | null;
PJ_PredictEndTime: string | null;
PJ_DemandURL: string | null;
PJ_IssueURL: string | null;
PJ_PlanURL: string | null;
} }
/** 监测状态摘要 */ /** 监测状态摘要 */