Merge pull request 'fix: 修复标题库新建/编辑功能 — 前后端字段名不匹配导致422' (#90) from fix/p0-create-titles-assets into develop
CI/CD Pipeline / Validate Code Quality And Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Lint (push) Has been cancelled
Deploy / Deploy Staging (push) Has been cancelled
Deploy / Build Production Runtime Images (push) Has been cancelled
Deploy / Deploy Production (push) Has been cancelled
Deploy / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / Validate Code Quality And Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Lint (push) Has been cancelled
Deploy / Deploy Staging (push) Has been cancelled
Deploy / Build Production Runtime Images (push) Has been cancelled
Deploy / Deploy Production (push) Has been cancelled
Deploy / Production Browser E2E (push) Has been cancelled
This commit was merged in pull request #90.
This commit is contained in:
+73
-11
@@ -1,10 +1,11 @@
|
||||
/**
|
||||
* 标题相关 API
|
||||
* Phase 1 新增:全局标题库
|
||||
* 注意:后端 schema 使用 name + text 字段,前端 UI 用 content 展示
|
||||
*/
|
||||
import apiClient from './client';
|
||||
|
||||
/** 标题条目 */
|
||||
/** 标题条目(前端展示用) */
|
||||
export interface TitleItem {
|
||||
id: string;
|
||||
content: string;
|
||||
@@ -16,7 +17,50 @@ export interface TitleItem {
|
||||
updated_at?: string;
|
||||
}
|
||||
|
||||
/** 创建标题请求 */
|
||||
/** 后端标题响应格式 */
|
||||
interface BackendTitleResponse {
|
||||
id: string;
|
||||
user_id: string;
|
||||
name: string;
|
||||
text: string;
|
||||
category: string;
|
||||
description: string;
|
||||
tags: string[];
|
||||
usage_count: number;
|
||||
is_active: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
/** 后端创建标题请求格式 */
|
||||
interface BackendCreateTitleRequest {
|
||||
name: string;
|
||||
text: string;
|
||||
category: string;
|
||||
description?: string;
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
/** 后端更新标题请求格式 */
|
||||
interface BackendUpdateTitleRequest {
|
||||
name?: string;
|
||||
text?: string;
|
||||
category?: string;
|
||||
description?: string;
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
/** 将后端响应映射为前端 TitleItem */
|
||||
const toTitleItem = (item: BackendTitleResponse): TitleItem => ({
|
||||
id: item.id,
|
||||
content: item.text,
|
||||
category: item.category,
|
||||
word_count: item.text?.length || 0,
|
||||
created_at: item.created_at,
|
||||
updated_at: item.updated_at,
|
||||
});
|
||||
|
||||
/** 创建标题请求(前端接口,保持向后兼容) */
|
||||
export interface CreateTitleRequest {
|
||||
content: string;
|
||||
category?: string;
|
||||
@@ -24,25 +68,43 @@ export interface CreateTitleRequest {
|
||||
|
||||
/** 获取当前用户的所有标题 */
|
||||
export const getTitles = async (): Promise<TitleItem[]> => {
|
||||
const response = await apiClient.get('/titles');
|
||||
return response.data.items || response.data || [];
|
||||
const response = await apiClient.get<{ items: BackendTitleResponse[] }>('/titles');
|
||||
return (response.data.items || []).map(toTitleItem);
|
||||
};
|
||||
|
||||
/** 创建标题 */
|
||||
export const createTitle = async (
|
||||
data: CreateTitleRequest
|
||||
data: CreateTitleRequest,
|
||||
): Promise<TitleItem> => {
|
||||
const response = await apiClient.post('/titles', data);
|
||||
return response.data;
|
||||
// 后端要求 name(≤255)和 text(≤500),name 从 content 截取
|
||||
const payload: BackendCreateTitleRequest = {
|
||||
name: data.content.slice(0, 255),
|
||||
text: data.content.slice(0, 500),
|
||||
category: data.category || 'default',
|
||||
};
|
||||
const response = await apiClient.post<BackendTitleResponse>('/titles', payload);
|
||||
return toTitleItem(response.data);
|
||||
};
|
||||
|
||||
/** 更新标题 */
|
||||
export const updateTitle = async (
|
||||
titleId: string,
|
||||
data: Partial<CreateTitleRequest>
|
||||
data: Partial<CreateTitleRequest>,
|
||||
): Promise<TitleItem> => {
|
||||
const response = await apiClient.patch(`/titles/${titleId}`, data);
|
||||
return response.data;
|
||||
const payload: BackendUpdateTitleRequest = {};
|
||||
if (data.content !== undefined) {
|
||||
payload.name = data.content.slice(0, 255);
|
||||
payload.text = data.content.slice(0, 500);
|
||||
}
|
||||
if (data.category !== undefined) {
|
||||
payload.category = data.category;
|
||||
}
|
||||
// 后端用 PUT,非 PATCH
|
||||
const response = await apiClient.put<BackendTitleResponse>(
|
||||
`/titles/${titleId}`,
|
||||
payload,
|
||||
);
|
||||
return toTitleItem(response.data);
|
||||
};
|
||||
|
||||
/** 删除标题 */
|
||||
@@ -52,7 +114,7 @@ export const deleteTitle = async (titleId: string): Promise<void> => {
|
||||
|
||||
/** 批量导入标题 */
|
||||
export const batchImportTitles = async (
|
||||
titles: string[]
|
||||
titles: string[],
|
||||
): Promise<{ imported_count: number }> => {
|
||||
const response = await apiClient.post('/titles/batch-import', { titles });
|
||||
return response.data;
|
||||
|
||||
Reference in New Issue
Block a user