| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- <script setup lang="ts">
- /** 契约自检页:把冻契约里的关键接口各取一次,显示 状态 / 耗时 / 顶层键。 */
- import { onMounted, ref } from 'vue'
- import { callApi, API_PATHS, SMOKE_SET, type ApiName } from '../api/contract'
- interface Row {
- name: ApiName
- path: string
- ok: boolean
- status: number
- ms: number
- keys: string
- error?: string
- }
- const rows = ref<Row[]>([])
- const running = ref(false)
- const finished = ref(0)
- function keysOf(data: unknown): string {
- if (Array.isArray(data)) return `list[${data.length}]`
- if (data && typeof data === 'object') return Object.keys(data as object).slice(0, 8).join(', ')
- return typeof data
- }
- async function run() {
- running.value = true
- rows.value = []
- finished.value = 0
- for (const name of SMOKE_SET) {
- const r = await callApi(name)
- rows.value.push({
- name,
- path: r.path,
- ok: r.ok,
- status: r.status,
- ms: r.ms,
- keys: keysOf(r.data),
- error: r.error,
- })
- finished.value += 1
- }
- running.value = false
- }
- onMounted(run)
- </script>
- <template>
- <section class="card">
- <h2>契约自检 <small>(后端结构与算法服务可达性;对拍基准见 docs/接口契约_前后端_v0.1.md)</small></h2>
- <p class="hint">
- 进度 {{ finished }}/{{ SMOKE_SET.length }} · 只判"通不通",不比数据值(值随数据变,锚点在 Python 侧的门禁里)
- <button class="re" :disabled="running" @click="run">重跑</button>
- </p>
- <table>
- <thead>
- <tr><th>接口</th><th>路径</th><th>状态</th><th>耗时</th><th>顶层键 / 形状</th></tr>
- </thead>
- <tbody>
- <tr v-for="r in rows" :key="r.name" :class="{ bad: !r.ok }">
- <td>{{ r.name }}</td>
- <td><code>{{ r.path }}</code></td>
- <td>{{ r.status }}</td>
- <td>{{ r.ms }} ms</td>
- <td>{{ r.error || r.keys }}</td>
- </tr>
- </tbody>
- </table>
- <p class="hint">
- 契约登记接口合计 {{ Object.keys(API_PATHS).length }} 条(本页抽样 {{ SMOKE_SET.length }} 条);
- 全量 42 条由 <code>python scripts/http_contract_audit.py</code> 在线复核。
- </p>
- </section>
- </template>
|