Files
xiaotutongxue/frontend-pc/.agents/skills/project-api/SKILL.md
T
lovife db6a51d617 docs: 清掉三处"会静默过期"的小账 + check-test-profile 加固(F-98)
一、附录 A 从"手抄表"改成"可再生成的命令"
   check-api-parity.py 加 --extra,现算"代码有、契约 §4 没有"的接口 = 41 个
   (旧手抄表写 83/62/21,已差近一倍,而且没人会记得回来改它)。
   并按"谁去改什么"分六类 —— 只有 E 类(8 个)要客户定口径,其余是文档侧补记。

二、F-6 已修:frontend-pc 的 Mock 说明
   AGENTS.md 那句改正之外,连带修了 .agents/skills/project-api/SKILL.md ——
   它整篇仍以 vite-plugin-mock / mock/** 为主线,而该项目里 mock/ 目录与插件都已删除。
   只改指路牌、不改路的尽头,等于没改。

三、docs/03 两处文档内部口径冲突加 ⚠️ 注(不改口径,只把冲突摆明)
   §2 notifyBizType 的 5/6 与 §13.5、落库值不一致 → 实现以 §13.5 为准(催报去重按 5);
   §3.6/§9.5 的 collect_file.source 字段表(入口来源)与建表注释(谁传的)冲突 →
   实现以建表口径为准。两处都写明"待客户确认",见 F-30 / F-38 / F-39。

四、check-test-profile.py 加固(新增 F-98)
   · 子进程输出落盘(不再用没人读的 PIPE):失败时能看见"停在哪一行",
     成功时打出启动用时(基线 ~10 秒 / 72 行 / 9.5KB);
   · 开跑前按 jar + profile 清残留 JVM,且保留 dev 后端(E2E 正打着它);
   · 等待期间每 15 秒报一次进度,卡住时不留沉默。
   教训:随机端口这个防撞设计把残留 JVM 藏起来了 —— 撞不到端口就永远发现不了,
   于是表现成"时好时坏",而失败时连日志都读不到。

验证:python scripts/verify-all.py --with-e2e → 通过 8 / 失败 0 / 跳过 0
      (E2E 36 脚本 / 1548 断言 / 278s;prodguard 9/9;test profile 能起)
      python scripts/verify-docs.py → 22 项全部通过
2026-09-30 09:10:34 +08:00

4.6 KiB
Raw Blame History

name, description
name description
project-api 在本模板项目中新增或修改 API 接口与类型定义(本仓库已不用 Mock,见开头说明)。涉及 http、baseAPI、分页响应格式、响应体适配时使用。

API 与 Mock

⚠️ 本仓库不用 Mock(2026-09-30 核实):mock/ 目录与 vite-plugin-mock 都已删除, .env.development 里 VITE_API_PREFIX = '/api/v1'、VITE_API_BASE_URL = 'http://localhost:8080', pnpm dev 把 /api 代理到真实后端 —— 后端不起着就没有数据(这不是故障)。

所以本文档里所有关于 Mock 的部分(mock/**、defineMock、getBaseApi 生成 mock、 Mock 目录约定)在本仓库不适用,保留它们只是因为 Gi 模板升级时要做差异比对。 新增接口照 src/apis/xt/*.ts 的写法:用 @/utils/http,响应体 { code, msg, data } (适配层会补 records)已在 @/utils/http 统一处理,业务模块不要再自己解一层。

接口层结构

每个业务模块一个文件,例如 src/apis/system/user.ts:

import { getBaseApi } from '@/apis/base'
import http from '@/utils/http'

export interface ListItem {
  id: string
  name: string
  status: Status
  createTime: string
  // ...
}

/** 标准 CRUD */
export const baseAPI = getBaseApi<ListItem>({ baseUrl: '/system/user' })

/** 非标准接口单独声明 */
export function getDictDataList(params: { code: string } & Pagination) {
  return http.get<PageRes<DictDataItem[]>>('/system/dict/getDictDataList', params)
}

getBaseApi 约定路径

方法 HTTP 路径
getList GET {baseUrl}/getList
getDetail GET {baseUrl}/getDetail
add POST {baseUrl}/add
update POST {baseUrl}/update
delete POST {baseUrl}/delete

列表参数:{ page, size, ...filters } 删除参数:{ ids: string[] }

响应格式

// 单条/布尔
interface ApiRes<T> {
  code: number
  data: T
  message: string
  success: boolean
}

// 分页列表 data 结构
interface PageRes<T> {
  records: T
  total: number
}

useTable 同时兼容 data 为数组或 PageRes 两种形态。

http 封装

  • 实例:src/utils/http.ts,baseURL = import.meta.env.VITE_API_PREFIX
  • 开发环境 .env.development:VITE_API_PREFIX = '/mock'
  • Token:请求头 token 字段(getToken())
  • 业务失败:success === false 时 Message/Notification 提示并 reject
  • 401:跳转 /login
import http from '@/utils/http'

http.get<PageRes<Item[]>>('/path', { page: 1, size: 10 })
http.post<boolean>('/path', { ids: ['1'] })

Mock 开发流程

1. 静态数据

在 mock/_data/ 下维护 JSON/TS 数据,如 system_dict.ts。

2. 路由 Mock

在 mock/system/(或对应模块)新建文件:

import { defineMock } from '../_base'
import { getBaseApi, getDelayTime, resultError, resultSuccess } from '../_utils'

export default defineMock([
  ...getBaseApi({
    baseUrl: '/system/xxx',
    getListData: () => resultSuccess({ total: list.length, records: list }),
    getDetailData: (query) => {
      const obj = list.find((i) => i.id === query.id)
      return obj ? resultSuccess(obj) : resultError(null, '未找到', 400)
    }
  }),
  {
    url: '/system/xxx/customAction',
    method: 'get',
    timeout: getDelayTime(),
    response: ({ query }) => {
      // 筛选、分页后返回
      return resultSuccess({ total, records })
    }
  }
])

3. 工具函数

函数 用途
resultSuccess(data) { code:200, success:true, data, message }
resultError(data, message, code?) 失败响应
getDelayTime() 50–300ms 随机延迟
getBaseApi({ baseUrl, getListData, ... }) 生成标准 CRUD mock

defineMock 会自动给 url 加前缀 /mock,与 VITE_API_PREFIX 对应。

4. 注册

确保 mock 文件被 mock/index 或同级聚合引入(遵循现有 mock/system/*.ts 模式)。

新增模块检查清单

  • src/apis/{module}/{name}.ts:类型 + baseAPI 或自定义方法
  • mock/{module}/{name}.ts:与接口路径一致
  • 列表 Mock 返回 { total, records }
  • 字段类型与 Status、Gender 等全局类型对齐
  • 在页面通过 useTable({ listAPI, deleteAPI }) 接入

自定义 listAPI 示例

useTable({
  listAPI: (page) => getDictDataList({
    ...page,
    code: dictCode.value,
    name: query.name || undefined,
    status: query.status === '' ? undefined : query.status
  }),
  immediate: false
})

immediate: false 用于依赖左侧选中项后再 search() 的场景。