Initial commit of akmon project
This commit is contained in:
708
pages/info/types.uts
Normal file
708
pages/info/types.uts
Normal file
@@ -0,0 +1,708 @@
|
||||
import { tt } from '@/utils/i18nfun.uts'
|
||||
|
||||
// 获取语言本地化 key(如 mt.language.zh-CN),用于 $t()
|
||||
export const getLanguageDisplayNameKey = (code: string): string => {
|
||||
if (code === 'zh-CN') return 'mt.language.zh-CN'
|
||||
if (code === 'zh-TW') return 'mt.language.zh-TW'
|
||||
if (code === 'en-US') return 'mt.language.en-US'
|
||||
if (code === 'ja-JP') return 'mt.language.ja-JP'
|
||||
if (code === 'ko-KR') return 'mt.language.ko-KR'
|
||||
if (code === 'fr-FR') return 'mt.language.fr-FR'
|
||||
if (code === 'de-DE') return 'mt.language.de-DE'
|
||||
if (code === 'es-ES') return 'mt.language.es-ES'
|
||||
return code
|
||||
}
|
||||
// 基础数据类型 - 全部使用强类型定义,便于类型推断和类型安全
|
||||
export type InfoContent = {
|
||||
id: string
|
||||
title?: string
|
||||
summary?: string | null
|
||||
content?: string
|
||||
author?: string
|
||||
trans_data?:TranslationData
|
||||
published_at?: string
|
||||
quality_score: number
|
||||
view_count?: number
|
||||
like_count?: number
|
||||
share_count?: number
|
||||
category_id?: string
|
||||
category_name?: CategoryTranslation
|
||||
category_name_text?: string // 兼容性字段,用于简单的字符串显示
|
||||
|
||||
original_language?: string
|
||||
source_url?: string | null
|
||||
tags?: string[] | null
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
is_liked?: boolean
|
||||
loading?: boolean // UI状态字段,用于加载状态显示
|
||||
|
||||
// 扩展字段 - 支持视频、音频和图集模式
|
||||
raw_content_id?: string | null
|
||||
keywords?: string[] | null
|
||||
entities?: any | null // jsonb
|
||||
sentiment_score?: number | null
|
||||
readability_score?: number | null
|
||||
credibility_score?: number | null
|
||||
comment_count?: number | null
|
||||
featured_until?: string | null
|
||||
status?: string | null
|
||||
ai_processed_at?: string | null
|
||||
favorite_count?: number | null
|
||||
is_featured?: boolean | null
|
||||
content_type?: string | null
|
||||
|
||||
// 视频相关字段
|
||||
video_url?: string | null
|
||||
video_duration?: number | null
|
||||
video_poster?: string | null
|
||||
video_width?: number | null
|
||||
video_height?: number | null
|
||||
video_size?: number | null
|
||||
video_format?: string | null
|
||||
video_quality?: string | null
|
||||
|
||||
// 音频相关字段
|
||||
audio_url?: string | null
|
||||
audio_duration?: number | null
|
||||
audio_size?: number | null
|
||||
audio_format?: string | null
|
||||
audio_bitrate?: number | null
|
||||
audio_sample_rate?: number | null
|
||||
audio_cover?: string | null
|
||||
|
||||
// 图片相关字段
|
||||
image_url?: string | null
|
||||
image_width?: number | null
|
||||
image_height?: number | null
|
||||
image_size?: number | null
|
||||
image_format?: string | null
|
||||
image_quality?: string | null
|
||||
image_alt_text?: string | null
|
||||
images?: any | null // jsonb - 图集模式
|
||||
|
||||
// 多媒体设置
|
||||
allow_danmu?: boolean | null
|
||||
allow_download?: boolean | null
|
||||
media_metadata?: any | null // jsonb
|
||||
|
||||
// 序列号字段
|
||||
cid?: number | null
|
||||
}
|
||||
|
||||
export type TranslationData = {
|
||||
id: string
|
||||
content_id: string
|
||||
language_id: string
|
||||
title: string
|
||||
content: string
|
||||
summary: string | null
|
||||
human_verified: boolean
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
// 新增:CategoryTranslation 类型
|
||||
export type CategoryTranslation = {
|
||||
name: string
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 新增:CategoryData 类型,严格对应 Supabase 返回结构
|
||||
export type CategoryData = {
|
||||
id: string
|
||||
name_key: string
|
||||
parent_id: string | null
|
||||
level?: number
|
||||
ai_keywords?: string[]
|
||||
confidence_threshold?: number
|
||||
sort_order?: number
|
||||
is_active?: boolean
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
translations?: CategoryTranslation[]
|
||||
}
|
||||
|
||||
// 新增专题相关类型
|
||||
export type TopicData = {
|
||||
id: string
|
||||
title: string
|
||||
description: string
|
||||
created_by: string
|
||||
is_active: boolean
|
||||
content_count: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export type TopicContentData = {
|
||||
id: string
|
||||
topic_id: string
|
||||
content_id: string
|
||||
display_order: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
is_liked?:boolean
|
||||
}
|
||||
|
||||
export type TopicTimelineData = {
|
||||
id: string
|
||||
topic_id: string
|
||||
event: string
|
||||
event_time: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
// 评论系统相关类型
|
||||
export type CommentData = {
|
||||
id: string
|
||||
content_id: string
|
||||
user_id: string
|
||||
user_name: string
|
||||
content: string
|
||||
like_count: number
|
||||
reply_count: number
|
||||
status: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
is_liked?: boolean
|
||||
level?: number // 多级评论层级,0为主评论,1为一级回复,依此类推
|
||||
is_author?: boolean // 是否为当前用户本人评论
|
||||
}
|
||||
|
||||
export type CommentReplyData = {
|
||||
id: string
|
||||
comment_id: string
|
||||
user_id: string
|
||||
user_name: string
|
||||
content: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
is_liked?:boolean
|
||||
}
|
||||
|
||||
export type CommentReactionData = {
|
||||
id: string
|
||||
comment_id: string
|
||||
user_id: string
|
||||
reaction_type: string
|
||||
created_at: string
|
||||
is_liked?:boolean
|
||||
}
|
||||
|
||||
export type UserBehaviorData = {
|
||||
id: string
|
||||
user_id: string
|
||||
content_id: string
|
||||
behavior_type: string
|
||||
behavior_data: any
|
||||
duration_seconds: number | null
|
||||
scroll_percentage: number | null
|
||||
device_type: string
|
||||
source: string
|
||||
session_id: string
|
||||
ip_address: string
|
||||
user_agent: string
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export type RecommendationData = {
|
||||
id: string
|
||||
user_id: string
|
||||
content_id: string
|
||||
algorithm_type: string
|
||||
score: number
|
||||
reason: string
|
||||
position: number
|
||||
shown_at: string
|
||||
clicked_at: string
|
||||
feedback_score: number
|
||||
feedback_reason: string
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export type ChatSessionData = {
|
||||
id: string
|
||||
user_id: string
|
||||
session_name: string
|
||||
language: string
|
||||
context: any
|
||||
ai_model: string
|
||||
total_messages: number
|
||||
total_tokens: number
|
||||
cost_usd: number
|
||||
last_message_at: string
|
||||
is_active: boolean
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export type ChatMessageData = {
|
||||
id: string
|
||||
session_id: string
|
||||
message_type: string
|
||||
content: string
|
||||
intent?: string
|
||||
attachments?: any
|
||||
ai_provider?: string
|
||||
tokens_used?: number
|
||||
processing_time_ms?: number
|
||||
cost_usd?: number
|
||||
feedback_score?: number
|
||||
feedback_reason?: string
|
||||
created_at?: string
|
||||
}
|
||||
|
||||
export type LanguageData = {
|
||||
id: string
|
||||
code: string
|
||||
name: string
|
||||
native_name: string
|
||||
is_active: boolean
|
||||
}
|
||||
|
||||
export type UserSettingsData = {
|
||||
id: string
|
||||
user_id: string
|
||||
preferred_languages: string[]
|
||||
preferred_categories: string[]
|
||||
reading_mode: string
|
||||
font_size: string
|
||||
auto_translate: boolean
|
||||
notification_enabled: boolean
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export type SearchHistoryData = {
|
||||
id: string
|
||||
user_id: string
|
||||
keyword: string
|
||||
searched_at: string
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 已合并到 TranslationData,避免重复定义
|
||||
// export type Translation = TranslationData
|
||||
|
||||
export type Topic = {
|
||||
id: string
|
||||
title: string
|
||||
description: string
|
||||
topic_type?: string
|
||||
status?: string
|
||||
cover_image?: string
|
||||
created_by?: string
|
||||
is_active?: boolean
|
||||
content_count?: number
|
||||
view_count?: number
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export type Comment = {
|
||||
id: string
|
||||
content_id: string
|
||||
user_id: string
|
||||
user_name: string
|
||||
content: string
|
||||
like_count: number
|
||||
reply_count: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
|
||||
|
||||
export type Language = {
|
||||
id: string
|
||||
code: string
|
||||
name: string
|
||||
native_name: string
|
||||
is_active: boolean
|
||||
}
|
||||
|
||||
// 状态和UI类型 - 与template交互的变量使用1维变量
|
||||
export type PageState = {
|
||||
loading: boolean
|
||||
error: string | null
|
||||
currentPage: number
|
||||
pageSize: number
|
||||
total: number
|
||||
}
|
||||
|
||||
export type StatsData = {
|
||||
total_contents: number
|
||||
published_contents: number
|
||||
trending_contents: number
|
||||
avg_quality_score: string
|
||||
}
|
||||
|
||||
export type ResponsiveState = {
|
||||
isLargeScreen: boolean
|
||||
isSmallScreen: boolean
|
||||
screenWidth: number
|
||||
cardColumns: number
|
||||
}
|
||||
|
||||
// 选择器选项类型 - UTS Android支持的简单类型
|
||||
export type PickerOption = {
|
||||
value: string
|
||||
text: string
|
||||
}
|
||||
|
||||
export type SortOption = {
|
||||
column: string
|
||||
ascending: boolean
|
||||
}
|
||||
|
||||
// 表单数据类型 - 避免复杂嵌套,使用简单类型
|
||||
export type ContentFormData = {
|
||||
title: string
|
||||
content: string
|
||||
summary: string
|
||||
category_id: string
|
||||
tags: string // 改为字符串,用逗号分隔
|
||||
source_url: string
|
||||
author: string
|
||||
content_type?: string
|
||||
|
||||
// 视频相关字段
|
||||
video_url?: string
|
||||
video_duration?: number
|
||||
video_poster?: string
|
||||
video_width?: number
|
||||
video_height?: number
|
||||
video_quality?: string
|
||||
|
||||
// 音频相关字段
|
||||
audio_url?: string
|
||||
audio_duration?: number
|
||||
audio_cover?: string
|
||||
audio_format?: string
|
||||
|
||||
// 图片相关字段
|
||||
image_url?: string
|
||||
image_alt_text?: string
|
||||
images?: string // JSON字符串存储图集数据
|
||||
|
||||
// 多媒体设置
|
||||
allow_danmu?: boolean
|
||||
allow_download?: boolean
|
||||
}
|
||||
|
||||
export type TranslationFormData = {
|
||||
content_id: string
|
||||
language_id: string
|
||||
title: string
|
||||
content: string
|
||||
summary: string
|
||||
}
|
||||
|
||||
// 筛选器类型 - 使用简单字符串类型
|
||||
export type ContentFilterData = {
|
||||
category_id: string | null
|
||||
language: string | null
|
||||
status: string
|
||||
quality_min: string | null
|
||||
date_from: string | null
|
||||
date_to: string | null
|
||||
search_text: string | null
|
||||
date_range?: string | null
|
||||
content_type?: string | null // 新增:按内容类型筛选
|
||||
is_featured?: boolean | null // 新增:是否精选
|
||||
has_video?: boolean | null // 新增:是否包含视频
|
||||
has_audio?: boolean | null // 新增:是否包含音频
|
||||
has_images?: boolean | null // 新增:是否包含图片
|
||||
}
|
||||
|
||||
// 聊天相关类型
|
||||
export type ChatState = {
|
||||
isTyping: boolean
|
||||
currentSession: string |null
|
||||
messageCount: number
|
||||
}
|
||||
|
||||
// 用户偏好类型 - 使用字符串存储数组数据
|
||||
export type UserPreferences = {
|
||||
preferred_languages: string // JSON字符串存储数组
|
||||
preferred_categories: string // JSON字符串存储数组
|
||||
reading_mode: string // 'light', 'dark', 'auto'
|
||||
font_size: string // 'small', 'medium', 'large'
|
||||
auto_translate: boolean
|
||||
notification_enabled: boolean
|
||||
}
|
||||
|
||||
|
||||
// 常量定义 - 内容状态
|
||||
export const CONTENT_STATUS = {
|
||||
DRAFT: 'draft',
|
||||
PUBLISHED: 'published',
|
||||
ARCHIVED: 'archived',
|
||||
DELETED: 'deleted'
|
||||
}
|
||||
|
||||
// 内容类型常量 - 支持多媒体
|
||||
export const CONTENT_TYPES = {
|
||||
TEXT: 'text', // 纯文本
|
||||
IMAGE: 'image', // 图片
|
||||
VIDEO: 'video', // 视频
|
||||
AUDIO: 'audio', // 音频
|
||||
GALLERY: 'gallery', // 图集
|
||||
MIXED: 'mixed' // 混合内容
|
||||
}
|
||||
|
||||
// 通用选项类型(用于 value/text 结构的所有 option)
|
||||
export type OptionItem = {
|
||||
value: string
|
||||
text: string
|
||||
}
|
||||
|
||||
// 视频质量选项
|
||||
export const VIDEO_QUALITY_OPTIONS: Array<OptionItem> = [
|
||||
{ value: '4K', text: 'mt.video.quality.4k' },
|
||||
{ value: '1080P', text: 'mt.video.quality.1080p' },
|
||||
{ value: '720P', text: 'mt.video.quality.720p' },
|
||||
{ value: '480P', text: 'mt.video.quality.480p' },
|
||||
{ value: '360P', text: 'mt.video.quality.360p' }
|
||||
]
|
||||
|
||||
// 音频格式选项
|
||||
export const AUDIO_FORMAT_OPTIONS: Array<OptionItem> = [
|
||||
{ value: 'mp3', text: 'mt.audio.format.mp3' },
|
||||
{ value: 'wav', text: 'mt.audio.format.wav' },
|
||||
{ value: 'flac', text: 'mt.audio.format.flac' },
|
||||
{ value: 'aac', text: 'mt.audio.format.aac' },
|
||||
{ value: 'm4a', text: 'mt.audio.format.m4a' }
|
||||
]
|
||||
|
||||
// 行为类型常量
|
||||
export const BEHAVIOR_TYPES = {
|
||||
VIEW: 'view',
|
||||
LIKE: 'like',
|
||||
SHARE: 'share',
|
||||
COMMENT: 'comment',
|
||||
SAVE: 'save',
|
||||
CLICK: 'click'
|
||||
}
|
||||
|
||||
// 消息类型常量
|
||||
export const MESSAGE_TYPES = {
|
||||
USER: 'user',
|
||||
ASSISTANT: 'assistant',
|
||||
SYSTEM: 'system'
|
||||
}
|
||||
|
||||
// 专题类型常量
|
||||
export const TOPIC_TYPES: Array<OptionItem> = [
|
||||
{ value: 'breaking', text: 'mt.topicType.breaking' },
|
||||
{ value: 'trending', text: 'mt.topicType.trending' },
|
||||
{ value: 'series', text: 'mt.topicType.series' },
|
||||
{ value: 'analysis', text: 'mt.topicType.analysis' },
|
||||
{ value: 'guide', text: 'mt.topicType.guide' },
|
||||
{ value: 'interview', text: 'mt.topicType.interview' },
|
||||
{ value: 'report', text: 'mt.topicType.report' },
|
||||
{ value: 'timeline', text: 'mt.topicType.timeline' }
|
||||
]
|
||||
|
||||
// 专题状态常量
|
||||
export const TOPIC_STATUS = {
|
||||
DRAFT: 'draft',
|
||||
ACTIVE: 'active',
|
||||
FEATURED: 'featured',
|
||||
ARCHIVED: 'archived',
|
||||
CLOSED: 'closed'
|
||||
}
|
||||
|
||||
// 评论状态常量
|
||||
export const COMMENT_STATUS = {
|
||||
ACTIVE: 'active',
|
||||
HIDDEN: 'hidden',
|
||||
DELETED: 'deleted',
|
||||
PENDING_REVIEW: 'pending_review',
|
||||
REJECTED: 'rejected'
|
||||
}
|
||||
|
||||
// 评论类型常量
|
||||
export const COMMENT_TYPES = {
|
||||
CONTENT: 'content', // 内容评论
|
||||
TOPIC: 'topic', // 专题评论
|
||||
REPLY: 'reply' // 回复评论
|
||||
}
|
||||
|
||||
// 评论排序选项
|
||||
export const COMMENT_SORT_OPTIONS: Array<OptionItem> = [
|
||||
{ value: 'created_at_desc', text: 'mt.comment.sort.latest' },
|
||||
{ value: 'created_at_asc', text: 'mt.comment.sort.earliest' },
|
||||
{ value: 'like_count_desc', text: 'mt.comment.sort.mostLiked' },
|
||||
{ value: 'reply_count_desc', text: 'mt.comment.sort.mostReplied' }
|
||||
]
|
||||
|
||||
// 评论举报类型
|
||||
export const COMMENT_REPORT_TYPES: Array<OptionItem> = [
|
||||
{ value: 'spam', text: 'mt.comment.report.spam' },
|
||||
{ value: 'inappropriate', text: 'mt.comment.report.inappropriate' },
|
||||
{ value: 'harassment', text: 'mt.comment.report.harassment' },
|
||||
{ value: 'misinformation', text: 'mt.comment.report.misinformation' },
|
||||
{ value: 'copyright', text: 'mt.comment.report.copyright' },
|
||||
{ value: 'other', text: 'mt.comment.report.other' }
|
||||
]
|
||||
|
||||
// 语言选项常量
|
||||
export const LANGUAGE_OPTIONS: Array<LanguageData> = [
|
||||
{ id: 'zh-CN', code: 'zh-CN', name: 'mt.language.zh-CN', native_name: 'mt.language.zh-CN', is_active: true },
|
||||
{ id: 'zh-TW', code: 'zh-TW', name: 'mt.language.zh-TW', native_name: 'mt.language.zh-TW', is_active: true },
|
||||
{ id: 'en-US', code: 'en-US', name: 'mt.language.en-US', native_name: 'mt.language.en-US', is_active: true },
|
||||
{ id: 'ja-JP', code: 'ja-JP', name: 'mt.language.ja-JP', native_name: 'mt.language.ja-JP', is_active: true },
|
||||
{ id: 'ko-KR', code: 'ko-KR', name: 'mt.language.ko-KR', native_name: 'mt.language.ko-KR', is_active: true },
|
||||
{ id: 'fr-FR', code: 'fr-FR', name: 'mt.language.fr-FR', native_name: 'mt.language.fr-FR', is_active: true },
|
||||
{ id: 'de-DE', code: 'de-DE', name: 'mt.language.de-DE', native_name: 'mt.language.de-DE', is_active: true },
|
||||
{ id: 'es-ES', code: 'es-ES', name: 'mt.language.es-ES', native_name: 'mt.language.es-ES', is_active: true }
|
||||
]
|
||||
export const SORT_OPTIONS: Array<OptionItem> = [
|
||||
{ value: 'published_at_desc', text: 'mt.sort.latest' },
|
||||
{ value: 'published_at_asc', text: 'mt.sort.earliest' },
|
||||
{ value: 'quality_score_desc', text: 'mt.sort.highestScore' },
|
||||
{ value: 'view_count_desc', text: 'mt.sort.mostViewed' },
|
||||
{ value: 'like_count_desc', text: 'mt.sort.mostLiked' },
|
||||
{ value: 'share_count_desc', text: 'mt.sort.mostShared' }
|
||||
]
|
||||
|
||||
|
||||
export const getCommentStatusTextKey = (status: string): string => {
|
||||
console.log(status,COMMENT_STATUS.HIDDEN)
|
||||
if (status === COMMENT_STATUS["ACTIVE"]) return 'mt.comment.status.active'
|
||||
if (status === COMMENT_STATUS.HIDDEN) return 'mt.comment.status.hidden'
|
||||
if (status === COMMENT_STATUS.DELETED) return 'mt.comment.status.deleted'
|
||||
if (status === COMMENT_STATUS.PENDING_REVIEW) return 'mt.comment.status.pending'
|
||||
if (status === COMMENT_STATUS.REJECTED) return 'mt.comment.status.rejected'
|
||||
return 'mt.comment.status.unknown'
|
||||
}
|
||||
|
||||
// 格式化相对时间,返回 i18n key
|
||||
export const formatRelativeTimeKey = (dateString: string | null): string => {
|
||||
if (dateString == null || dateString === '') return ''
|
||||
const now = new Date()
|
||||
const date = new Date(dateString)
|
||||
const diff = now.getTime() - date.getTime()
|
||||
const seconds = Math.floor(diff / 1000)
|
||||
const minutes = Math.floor(seconds / 60)
|
||||
const hours = Math.floor(minutes / 60)
|
||||
const days = Math.floor(hours / 24)
|
||||
if (days > 0) return days + tt('mt.time.daysAgo')
|
||||
if (hours > 0) return hours + tt('mt.time.hoursAgo')
|
||||
if (minutes > 0) return minutes + tt('mt.time.minutesAgo')
|
||||
return tt('mt.time.justNow')
|
||||
}
|
||||
|
||||
|
||||
// 语言显示名称,返回本地化字符串
|
||||
export const getLanguageDisplayName = (code: string): string => {
|
||||
const map = {
|
||||
'zh-CN': 'mt.language.zh-CN',
|
||||
'zh-TW': 'mt.language.zh-TW',
|
||||
'en-US': 'mt.language.en-US',
|
||||
'ja-JP': 'mt.language.ja-JP',
|
||||
'ko-KR': 'mt.language.ko-KR',
|
||||
'fr-FR': 'mt.language.fr-FR',
|
||||
'de-DE': 'mt.language.de-DE',
|
||||
'es-ES': 'mt.language.es-ES'
|
||||
}
|
||||
const key = map[code] ?? code
|
||||
return tt(key)
|
||||
}
|
||||
|
||||
// 质量分数对应颜色,返回颜色字符串(如需 className 可调整)
|
||||
export const getQualityScoreColor = (score: number): string => {
|
||||
if (score >= 90) return '#4CAF50' // excellent - green
|
||||
if (score >= 75) return '#8BC34A' // good - light green
|
||||
if (score >= 60) return '#FFC107' // normal - amber
|
||||
return '#F44336' // poor - red
|
||||
}
|
||||
|
||||
// 质量分数对应文本,返回 i18n key
|
||||
export const getQualityScoreText = (score: number): string => {
|
||||
if (score >= 90) return tt('mt.quality.excellent')
|
||||
if (score >= 75) return tt('mt.quality.good')
|
||||
if (score >= 60) return tt('mt.quality.normal')
|
||||
return tt('mt.quality.poor')
|
||||
}
|
||||
|
||||
// 专题类型显示名称,返回本地化字符串
|
||||
export const getTopicTypeDisplayName = (typeCode: string): string => {
|
||||
const typeItem = TOPIC_TYPES.find(item => item.value === typeCode);
|
||||
return typeItem != null ? tt(typeItem.text) : typeCode;
|
||||
};
|
||||
|
||||
// 专题状态对应颜色,返回颜色字符串
|
||||
export const getTopicStatusColor = (status: string): string => {
|
||||
if (status === TOPIC_STATUS.FEATURED) return '#FF6B35' // featured - orange
|
||||
if (status === TOPIC_STATUS.ACTIVE) return '#4CAF50' // active - green
|
||||
if (status === TOPIC_STATUS.DRAFT) return '#9E9E9E' // draft - gray
|
||||
if (status === TOPIC_STATUS.ARCHIVED) return '#607D8B' // archived - blue gray
|
||||
if (status === TOPIC_STATUS.CLOSED) return '#F44336' // closed - red
|
||||
return '#9E9E9E' // default - gray
|
||||
}
|
||||
|
||||
// 获取内容类型显示名称,返回本地化字符串
|
||||
export const getContentTypeDisplayName = (contentType: string | null): string => {
|
||||
if (contentType === CONTENT_TYPES.TEXT) return tt('mt.content.type.text')
|
||||
if (contentType === CONTENT_TYPES.IMAGE) return tt('mt.content.type.image')
|
||||
if (contentType === CONTENT_TYPES.VIDEO) return tt('mt.content.type.video')
|
||||
if (contentType === CONTENT_TYPES.AUDIO) return tt('mt.content.type.audio')
|
||||
if (contentType === CONTENT_TYPES.GALLERY) return tt('mt.content.type.gallery')
|
||||
if (contentType === CONTENT_TYPES.MIXED) return tt('mt.content.type.mixed')
|
||||
return tt('mt.content.type.text') // 默认为文本
|
||||
}
|
||||
|
||||
// 获取内容类型对应图标
|
||||
export const getContentTypeIcon = (contentType: string | null): string => {
|
||||
if (contentType === CONTENT_TYPES.TEXT) return 'text-outline'
|
||||
if (contentType === CONTENT_TYPES.IMAGE) return 'image-outline'
|
||||
if (contentType === CONTENT_TYPES.VIDEO) return 'videocam-outline'
|
||||
if (contentType === CONTENT_TYPES.AUDIO) return 'volume-high-outline'
|
||||
if (contentType === CONTENT_TYPES.GALLERY) return 'images-outline'
|
||||
if (contentType === CONTENT_TYPES.MIXED) return 'layers-outline'
|
||||
return 'text-outline' // 默认图标
|
||||
}
|
||||
|
||||
// 格式化文件大小
|
||||
export const formatFileSize = (bytes: number | null): string => {
|
||||
if (bytes == null || bytes === 0) return '0 B'
|
||||
const k = 1024
|
||||
const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
||||
}
|
||||
|
||||
// 格式化时长(秒转为 mm:ss 或 hh:mm:ss)
|
||||
export const formatDuration = (seconds: number | null): string => {
|
||||
if (seconds == null || seconds === 0) return '00:00'
|
||||
const hours = Math.floor(seconds / 3600)
|
||||
const minutes = Math.floor((seconds % 3600) / 60)
|
||||
const remainingSeconds = Math.floor(seconds % 60)
|
||||
|
||||
if (hours > 0) {
|
||||
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`
|
||||
} else {
|
||||
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`
|
||||
}
|
||||
}
|
||||
|
||||
// 检查内容是否有多媒体
|
||||
export const hasMultimedia = (content: InfoContent): boolean => {
|
||||
return !!(content.video_url || content.audio_url || content.image_url || (content.images && content.images !== null))
|
||||
}
|
||||
|
||||
// 获取主要媒体类型
|
||||
export const getPrimaryMediaType = (content: InfoContent): string => {
|
||||
if (content.video_url) return CONTENT_TYPES.VIDEO
|
||||
if (content.audio_url) return CONTENT_TYPES.AUDIO
|
||||
if (content.images && content.images !== null) return CONTENT_TYPES.GALLERY
|
||||
if (content.image_url) return CONTENT_TYPES.IMAGE
|
||||
return CONTENT_TYPES.TEXT
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user