129 lines
3.4 KiB
TypeScript
129 lines
3.4 KiB
TypeScript
|
|
/**
|
|||
|
|
* 帖子数据映射器
|
|||
|
|
* 负责 Post 模型与 API 响应之间的转换
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import { PostModel, UserModel } from '../models';
|
|||
|
|
import type { PostDTO } from '../../types/dto';
|
|||
|
|
|
|||
|
|
export class PostMapper {
|
|||
|
|
static fromApiResponse(response: PostDTO): PostModel {
|
|||
|
|
return {
|
|||
|
|
id: String(response.id || ''),
|
|||
|
|
authorId: String(response.user_id || ''),
|
|||
|
|
author: response.author ? this.mapAuthorFromApi(response.author) : undefined,
|
|||
|
|
title: response.title || '',
|
|||
|
|
content: response.content || '',
|
|||
|
|
images: response.images?.map(img => img.url) || [],
|
|||
|
|
likeCount: response.likes_count || 0,
|
|||
|
|
commentCount: response.comments_count || 0,
|
|||
|
|
shareCount: response.shares_count || 0,
|
|||
|
|
viewCount: response.views_count || 0,
|
|||
|
|
favoriteCount: response.favorites_count || 0,
|
|||
|
|
isLiked: response.is_liked || false,
|
|||
|
|
isFavorited: response.is_favorited || false,
|
|||
|
|
isTop: response.is_pinned || false,
|
|||
|
|
status: (response.status || 'published') as 'published' | 'draft' | 'deleted',
|
|||
|
|
channelId: response.channel_id,
|
|||
|
|
channel:
|
|||
|
|
response.channel && response.channel.id
|
|||
|
|
? { id: String(response.channel.id), name: String(response.channel.name || '') }
|
|||
|
|
: undefined,
|
|||
|
|
tags: [],
|
|||
|
|
createdAt: new Date(response.created_at || Date.now()),
|
|||
|
|
// 空字符串/缺省时用 created_at,避免误用 Date.now() 导致全部显示「刚修改」
|
|||
|
|
updatedAt: new Date(
|
|||
|
|
response.updated_at ||
|
|||
|
|
response.created_at ||
|
|||
|
|
Date.now()
|
|||
|
|
),
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 将 API 响应数组转换为应用模型数组
|
|||
|
|
*/
|
|||
|
|
static fromApiResponseList(responses: PostDTO[]): PostModel[] {
|
|||
|
|
return responses.map(r => this.fromApiResponse(r));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 将应用模型转换为 API 请求数据
|
|||
|
|
*/
|
|||
|
|
static toApiRequest(model: Partial<PostModel>): Record<string, any> {
|
|||
|
|
const request: Record<string, any> = {};
|
|||
|
|
|
|||
|
|
if (model.title !== undefined) {
|
|||
|
|
request.title = model.title;
|
|||
|
|
}
|
|||
|
|
if (model.content !== undefined) {
|
|||
|
|
request.content = model.content;
|
|||
|
|
}
|
|||
|
|
if (model.images !== undefined) {
|
|||
|
|
request.images = model.images;
|
|||
|
|
}
|
|||
|
|
if (model.channelId !== undefined) {
|
|||
|
|
request.channel_id = model.channelId;
|
|||
|
|
}
|
|||
|
|
if (model.tags !== undefined) {
|
|||
|
|
request.tags = model.tags;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return request;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 创建帖子请求
|
|||
|
|
*/
|
|||
|
|
static createPostRequest(
|
|||
|
|
title: string,
|
|||
|
|
content: string,
|
|||
|
|
images?: string[],
|
|||
|
|
channelId?: string
|
|||
|
|
): Record<string, any> {
|
|||
|
|
const request: Record<string, any> = {
|
|||
|
|
title,
|
|||
|
|
content,
|
|||
|
|
};
|
|||
|
|
if (images && images.length > 0) {
|
|||
|
|
request.images = images;
|
|||
|
|
}
|
|||
|
|
if (channelId) {
|
|||
|
|
request.channel_id = channelId;
|
|||
|
|
}
|
|||
|
|
return request;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 更新帖子请求
|
|||
|
|
*/
|
|||
|
|
static updatePostRequest(
|
|||
|
|
title?: string,
|
|||
|
|
content?: string,
|
|||
|
|
images?: string[]
|
|||
|
|
): Record<string, any> {
|
|||
|
|
const request: Record<string, any> = {};
|
|||
|
|
if (title !== undefined) {
|
|||
|
|
request.title = title;
|
|||
|
|
}
|
|||
|
|
if (content !== undefined) {
|
|||
|
|
request.content = content;
|
|||
|
|
}
|
|||
|
|
if (images !== undefined) {
|
|||
|
|
request.images = images;
|
|||
|
|
}
|
|||
|
|
return request;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 映射作者信息
|
|||
|
|
*/
|
|||
|
|
private static mapAuthorFromApi(author: any): UserModel {
|
|||
|
|
return {
|
|||
|
|
id: String(author.id || ''),
|
|||
|
|
username: author.username || '',
|
|||
|
|
nickname: author.nickname,
|
|||
|
|
avatar: author.avatar,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|