yuanjing/src/utlis/transform.ts
2026-06-04 11:17:47 +08:00

114 lines
3.7 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.

// utils/transform.ts
import type { FeedItem, StencilItem, ShareElementItem, ShortFilm, Tutorial, MediaAsset } from '../types/home';
type FeedItemData = ShortFilm | Tutorial | MediaAsset;
export function transformFeedItem(item: FeedItem): StencilItem | null {
// 根据 type 确定实际数据来源
let data: FeedItemData | null = null;
if (item.type === 'short_film' && item.short_film) {
data = item.short_film;
} else if (item.type === 'tutorial' && item.tutorial) {
data = item.tutorial;
} else if (item.type === 'media_asset' && item.media_asset) {
data = item.media_asset;
} else {
return null;
}
if (!data) return null;
const creation = data.creation;
if (!creation) return null;
// 构建宽高比字符串CSS 支持 "宽/高" 格式)
const { width, height } = creation.size;
const aspectRatio = `${width}/${height}`;
return {
id: data.id,
type: 'video', // 当前所有项都是视频,可根据实际情况调整
src: creation.uri,
poster: creation.cover_uri,
aspectRatio,
avatar: data.creator?.avatar ?? '',
userName: data.creator?.nick_name ?? '',
likes: data.react_info?.vote_count ?? 0,
title: 'title' in data ? data.title : data.tag || data.brief || '未命名作品',
description: data.detail || ('brief' in data ? data.brief : '') || '',
createdAt: data.created_at || '',
contentType: item.type,
displayTag: 'tag' in data ? data.tag : data.type,
collectCount: data.react_info?.collect_count ?? 0,
recreateCount: 'recreate_count' in data ? data.recreate_count : undefined,
creatorId: data.creator?.id ?? '',
};
}
/**
* 转换 Share Elements 数据格式为 StencilItem 格式
*/
export function transformShareElementItem(item: ShareElementItem): StencilItem | null {
const element = item.element;
const share = item.share;
if (!element || !share) return null;
// 尝试从 creations 中获取第一个视频/图片
const firstCreation = share.creations?.[0];
let src = '';
let poster = '';
let aspectRatio = '1/1';
if (firstCreation) {
// 从 creation 获取
src = firstCreation.uri;
poster = firstCreation.cover_uri;
// 计算宽高比
const width = firstCreation.resolution?.width || 1920;
const height = firstCreation.resolution?.height || 1080;
aspectRatio = `${width}/${height}`;
}
// else if (element.components?.[0]) {
// // 从 components 获取(降级方案)
// const component = element.components[0];
// src = component.content;
// poster = component.cover_uri || component.src_img;
// // 尝试从 selected_region 获取宽高
// if (component.selected_region) {
// const { x: x1, y: y1 } = component.selected_region.top_left;
// const { x: x2, y: y2 } = component.selected_region.bottom_right;
// const width = x2 - x1;
// const height = y2 - y1;
// if (width > 0 && height > 0) {
// aspectRatio = `${width}/${height}`;
// }
// }
// }
// 如果仍然没有数据,返回 null
if (!src) return null;
// 如果没有 poster使用 src 作为 poster
if (!poster) poster = src;
return {
id: element.id,
type: 'video',
src,
poster,
aspectRatio,
avatar: element.creator?.avatar ?? '',
userName: element.creator?.nick_name ?? '',
likes: share.react_info?.vote_count ?? 0,
title: element.name || '未命名作品',
description: share.introduce || element.recaption?.description || '',
createdAt: share.created_at || element.created_at || '',
contentType: 'share_elements',
displayTag: share.category_display?.[0] || element.type || '素材',
collectCount: share.react_info?.collect_count ?? 0,
creatorId: element.creator?.id ?? '',
};
}