lty/qy-lty-admin/lib/api/credential-slot.ts
pmc a0d0b9c1ad feat(01-01): 新建 lib/api/credential-slot.ts 凭据槽位 API 客户端
- 类型 CredentialSlot { appId, accessTokenMasked, updatedAt }(脱敏掩码语义命名)
- 类型 CredentialSlotUpdatePayload { appId, accessToken }(明文语义命名)
- 内部接口 BackendCredentialSlot(snake_case,不导出)
- adapter mapBackendCredentialSlot 把 snake → camel
- getCredentialSlot() 走 apiClient.get '/v1/admin/credential-slot/'
- updateCredentialSlot(payload) 走 apiClient.put '/v1/admin/credential-slot/',body 仅 { app_id, access_token } 不带 updated_at
- GET / PUT 各含一次 response.data?.data || response.data 双保险解包
- 1:1 复刻 lib/api/ai-models.ts 风格
2026-05-08 11:02:35 +08:00

65 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { apiClient } from "./client"
// ───── 后端响应原始 dictsnake_case仅 adapter 内部用,不导出)────────────
interface BackendCredentialSlot {
app_id: string
access_token: string
updated_at: string
}
// ───── 前端响应类型camelCase导出给 UI 层 import──────────────────────
/**
* 凭据槽位(后端响应)。
* 注意access_token 已是脱敏掩码(末 4 位明文),不要把它当明文回写。
*/
export interface CredentialSlot {
appId: string
accessTokenMasked: string // 后端返回的脱敏字符串
updatedAt: string // ISO 8601
}
// ───── 提交载荷类型(camelCase 明文)──────────────────────────────────────
/**
* 凭据槽位更新载荷。
* 注意accessToken 是明文,提交后将完整覆写后端记录。
*/
export interface CredentialSlotUpdatePayload {
appId: string
accessToken: string // 明文
}
// ───── adapter后端 → 前端)─────────────────────────────────────────────
function mapBackendCredentialSlot(raw: BackendCredentialSlot): CredentialSlot {
return {
appId: raw.app_id,
accessTokenMasked: raw.access_token,
updatedAt: raw.updated_at,
}
}
// ───── API 函数 ──────────────────────────────────────────────────────────
/**
* 读取当前凭据槽位access_token 字段为脱敏掩码)。
*/
export const getCredentialSlot = async (): Promise<CredentialSlot> => {
const response = await apiClient.get('/v1/admin/credential-slot/')
const data = response.data?.data || response.data // 仓库统一双保险解包
return mapBackendCredentialSlot(data)
}
/**
* 全字段覆写凭据槽位access_token 必须为明文;响应里返回的同样是脱敏掩码)。
*/
export const updateCredentialSlot = async (
payload: CredentialSlotUpdatePayload
): Promise<CredentialSlot> => {
const body = {
app_id: payload.appId,
access_token: payload.accessToken,
// 不带 updated_at —— 后端 auto_now 维护,与 updateOutfit / updateAiModel 风格一致
}
const response = await apiClient.put('/v1/admin/credential-slot/', body)
const data = response.data?.data || response.data
return mapBackendCredentialSlot(data)
}