sentiment analysisi
This commit is contained in:
@@ -138,6 +138,43 @@ interface DashboardCardsResponse {
|
|||||||
error?: string;
|
error?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加平台分布API响应接口
|
||||||
|
interface PlatformDistributionResponse {
|
||||||
|
success: boolean;
|
||||||
|
data: {
|
||||||
|
platform: string;
|
||||||
|
count: number;
|
||||||
|
percentage: number;
|
||||||
|
}[];
|
||||||
|
metadata: {
|
||||||
|
total: number;
|
||||||
|
event_type: string;
|
||||||
|
};
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加情感分析API响应接口
|
||||||
|
interface SentimentAnalysisResponse {
|
||||||
|
success: boolean;
|
||||||
|
data: {
|
||||||
|
positive: {
|
||||||
|
count: number;
|
||||||
|
percentage: number;
|
||||||
|
};
|
||||||
|
neutral: {
|
||||||
|
count: number;
|
||||||
|
percentage: number;
|
||||||
|
};
|
||||||
|
negative: {
|
||||||
|
count: number;
|
||||||
|
percentage: number;
|
||||||
|
};
|
||||||
|
total: number;
|
||||||
|
average_score: number;
|
||||||
|
};
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
|
||||||
// 添加留言趋势API响应接口
|
// 添加留言趋势API响应接口
|
||||||
interface CommentTrendResponse {
|
interface CommentTrendResponse {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
@@ -220,6 +257,12 @@ const Analytics: React.FC = () => {
|
|||||||
const [cardsLoading, setCardsLoading] = useState(true);
|
const [cardsLoading, setCardsLoading] = useState(true);
|
||||||
const [cardsError, setCardsError] = useState<string | null>(null);
|
const [cardsError, setCardsError] = useState<string | null>(null);
|
||||||
|
|
||||||
|
const [platformLoading, setPlatformLoading] = useState(true);
|
||||||
|
const [platformError, setPlatformError] = useState<string | null>(null);
|
||||||
|
const [sentimentLoading, setSentimentLoading] = useState(true);
|
||||||
|
const [sentimentError, setSentimentError] = useState<string | null>(null);
|
||||||
|
const [sentimentScore, setSentimentScore] = useState(0);
|
||||||
|
|
||||||
// 获取KOL概览数据
|
// 获取KOL概览数据
|
||||||
const fetchKolOverviewData = async () => {
|
const fetchKolOverviewData = async () => {
|
||||||
setKolLoading(true);
|
setKolLoading(true);
|
||||||
@@ -301,21 +344,17 @@ const Analytics: React.FC = () => {
|
|||||||
// 获取留言趋势数据
|
// 获取留言趋势数据
|
||||||
fetchCommentTrend();
|
fetchCommentTrend();
|
||||||
|
|
||||||
|
// 获取平台分布数据
|
||||||
|
fetchPlatformDistribution();
|
||||||
|
|
||||||
|
// 获取情感分析数据
|
||||||
|
fetchSentimentAnalysis();
|
||||||
|
|
||||||
const fetchAnalyticsData = async () => {
|
const fetchAnalyticsData = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
// Set default platform distribution data
|
// 删除平台分布的硬编码数据,使用API数据替代
|
||||||
setPlatformData([
|
|
||||||
{ name: 'Facebook', value: 35, color: '#1877F2' },
|
|
||||||
{ name: 'Twitter', value: 25, color: '#1DA1F2' },
|
|
||||||
{ name: 'Instagram', value: 20, color: '#E4405F' },
|
|
||||||
{ name: 'LinkedIn', value: 15, color: '#0A66C2' },
|
|
||||||
{ name: 'YouTube', value: 5, color: '#FF0000' }
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Set mock sentiment data
|
|
||||||
setSentimentData({ positive: 65, neutral: 20, negative: 15 });
|
|
||||||
|
|
||||||
// Set mock status data
|
// Set mock status data
|
||||||
setStatusData([
|
setStatusData([
|
||||||
@@ -999,6 +1038,180 @@ const Analytics: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取平台分布数据
|
||||||
|
const fetchPlatformDistribution = async () => {
|
||||||
|
try {
|
||||||
|
setPlatformLoading(true);
|
||||||
|
setPlatformError(null);
|
||||||
|
|
||||||
|
// 构建平台分布API URL
|
||||||
|
const url = `http://localhost:4000/api/analytics/platform-distribution?timeRange=${timeRange}`;
|
||||||
|
|
||||||
|
// 添加项目过滤参数(如果选择了特定项目)
|
||||||
|
const urlWithFilters = selectedProject !== 'all'
|
||||||
|
? `${url}&projectId=${selectedProject}`
|
||||||
|
: url;
|
||||||
|
|
||||||
|
// 添加平台过滤参数(如果选择了特定平台)
|
||||||
|
const finalUrl = selectedPlatform !== 'all'
|
||||||
|
? `${urlWithFilters}&platform=${selectedPlatform}`
|
||||||
|
: urlWithFilters;
|
||||||
|
|
||||||
|
console.log('请求平台分布数据URL:', finalUrl);
|
||||||
|
|
||||||
|
// 添加认证头
|
||||||
|
const authToken = 'eyJhbGciOiJIUzI1NiIsImtpZCI6Inl3blNGYnRBOGtBUnl4UmUiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3h0cWhsdXpvcm5hemxta29udWNyLnN1cGFiYXNlLmNvL2F1dGgvdjEiLCJzdWIiOiI1YjQzMThiZi0yMWE4LTQ3YWMtOGJmYS0yYThmOGVmOWMwZmIiLCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzQxNjI3ODkyLCJpYXQiOjE3NDE2MjQyOTIsImVtYWlsIjoidml0YWxpdHltYWlsZ0BnbWFpbC5jb20iLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7ImVtYWlsX3ZlcmlmaWVkIjp0cnVlfSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc0MTYyNDI5Mn1dLCJzZXNzaW9uX2lkIjoiODlmYjg0YzktZmEzYy00YmVlLTk0MDQtNjI1MjE0OGIyMzVlIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.VuUX2yhqN-FZseKL8fQG91i1cohfRqW2m1Z8CIWhZuk';
|
||||||
|
|
||||||
|
const response = await fetch(finalUrl, {
|
||||||
|
headers: {
|
||||||
|
'accept': 'application/json',
|
||||||
|
'Authorization': `Bearer ${authToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const result = await response.json() as PlatformDistributionResponse;
|
||||||
|
console.log('成功获取平台分布数据:', result);
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
// 平台名称规范化并合并相同平台(大小写不同)
|
||||||
|
const platformMap = new Map<string, { count: number; percentage: number; color: string }>();
|
||||||
|
|
||||||
|
// 为不同平台分配颜色
|
||||||
|
const platformColors: Record<string, string> = {
|
||||||
|
'facebook': '#1877F2',
|
||||||
|
'twitter': '#1DA1F2',
|
||||||
|
'instagram': '#E4405F',
|
||||||
|
'linkedin': '#0A66C2',
|
||||||
|
'youtube': '#FF0000',
|
||||||
|
'tiktok': '#000000',
|
||||||
|
'xiaohongshu': '#FF0000'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理并合并平台数据
|
||||||
|
result.data.forEach((item) => {
|
||||||
|
const platformLower = item.platform.toLowerCase();
|
||||||
|
const existingData = platformMap.get(platformLower);
|
||||||
|
|
||||||
|
if (existingData) {
|
||||||
|
// 合并相同平台(大小写不同)的数据
|
||||||
|
platformMap.set(platformLower, {
|
||||||
|
count: existingData.count + item.count,
|
||||||
|
percentage: existingData.percentage + item.percentage,
|
||||||
|
color: existingData.color
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 添加新平台数据
|
||||||
|
platformMap.set(platformLower, {
|
||||||
|
count: item.count,
|
||||||
|
percentage: item.percentage,
|
||||||
|
color: platformColors[platformLower] || '#808080' // 默认为灰色
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 将处理后的数据转换为AnalyticsData数组
|
||||||
|
const mappedData: AnalyticsData[] = Array.from(platformMap.entries()).map(([name, data]) => ({
|
||||||
|
name: name,
|
||||||
|
value: data.count,
|
||||||
|
percentage: data.percentage,
|
||||||
|
color: data.color
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 按百分比降序排序
|
||||||
|
mappedData.sort((a, b) => (b.percentage || 0) - (a.percentage || 0));
|
||||||
|
|
||||||
|
// 更新状态
|
||||||
|
setPlatformData(mappedData);
|
||||||
|
|
||||||
|
// 如果API返回了模拟数据标志
|
||||||
|
if ('is_mock_data' in result && result.is_mock_data) {
|
||||||
|
console.info('注意: 使用的是模拟平台分布数据');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setPlatformError(result.error || '获取平台分布数据失败');
|
||||||
|
console.error('API调用失败:', result.error || '未知错误');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const errorText = await response.text();
|
||||||
|
setPlatformError(`获取失败 (${response.status}): ${errorText}`);
|
||||||
|
console.error('获取平台分布数据失败,HTTP状态:', response.status, errorText);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setPlatformError(`获取平台分布数据时发生错误: ${error instanceof Error ? error.message : String(error)}`);
|
||||||
|
console.error('获取平台分布数据时发生错误:', error);
|
||||||
|
} finally {
|
||||||
|
setPlatformLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取情感分析数据
|
||||||
|
const fetchSentimentAnalysis = async () => {
|
||||||
|
try {
|
||||||
|
setSentimentLoading(true);
|
||||||
|
setSentimentError(null);
|
||||||
|
|
||||||
|
// 构建情感分析API URL
|
||||||
|
const url = `http://localhost:4000/api/analytics/sentiment-analysis?timeRange=${timeRange}`;
|
||||||
|
|
||||||
|
// 添加项目过滤参数(如果选择了特定项目)
|
||||||
|
const urlWithFilters = selectedProject !== 'all'
|
||||||
|
? `${url}&projectId=${selectedProject}`
|
||||||
|
: url;
|
||||||
|
|
||||||
|
// 添加平台过滤参数(如果选择了特定平台)
|
||||||
|
const finalUrl = selectedPlatform !== 'all'
|
||||||
|
? `${urlWithFilters}&platform=${selectedPlatform}`
|
||||||
|
: urlWithFilters;
|
||||||
|
|
||||||
|
console.log('请求情感分析数据URL:', finalUrl);
|
||||||
|
|
||||||
|
// 添加认证头
|
||||||
|
const authToken = 'eyJhbGciOiJIUzI1NiIsImtpZCI6Inl3blNGYnRBOGtBUnl4UmUiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3h0cWhsdXpvcm5hemxta29udWNyLnN1cGFiYXNlLmNvL2F1dGgvdjEiLCJzdWIiOiI1YjQzMThiZi0yMWE4LTQ3YWMtOGJmYS0yYThmOGVmOWMwZmIiLCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzQxNjI3ODkyLCJpYXQiOjE3NDE2MjQyOTIsImVtYWlsIjoidml0YWxpdHltYWlsZ0BnbWFpbC5jb20iLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7ImVtYWlsX3ZlcmlmaWVkIjp0cnVlfSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc0MTYyNDI5Mn1dLCJzZXNzaW9uX2lkIjoiODlmYjg0YzktZmEzYy00YmVlLTk0MDQtNjI1MjE0OGIyMzVlIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.VuUX2yhqN-FZseKL8fQG91i1cohfRqW2m1Z8CIWhZuk';
|
||||||
|
|
||||||
|
const response = await fetch(finalUrl, {
|
||||||
|
headers: {
|
||||||
|
'accept': 'application/json',
|
||||||
|
'Authorization': `Bearer ${authToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const result = await response.json() as SentimentAnalysisResponse;
|
||||||
|
console.log('成功获取情感分析数据:', result);
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
// 更新状态
|
||||||
|
setSentimentData({
|
||||||
|
positive: result.data.positive.percentage,
|
||||||
|
neutral: result.data.neutral.percentage,
|
||||||
|
negative: result.data.negative.percentage
|
||||||
|
});
|
||||||
|
|
||||||
|
// 设置平均情感分数
|
||||||
|
setSentimentScore(result.data.average_score);
|
||||||
|
|
||||||
|
// 如果API返回了模拟数据标志
|
||||||
|
if ('is_mock_data' in result && result.is_mock_data) {
|
||||||
|
console.info('注意: 使用的是模拟情感分析数据');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setSentimentError(result.error || '获取情感分析数据失败');
|
||||||
|
console.error('API调用失败:', result.error || '未知错误');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const errorText = await response.text();
|
||||||
|
setSentimentError(`获取失败 (${response.status}): ${errorText}`);
|
||||||
|
console.error('获取情感分析数据失败,HTTP状态:', response.status, errorText);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setSentimentError(`获取情感分析数据时发生错误: ${error instanceof Error ? error.message : String(error)}`);
|
||||||
|
console.error('获取情感分析数据时发生错误:', error);
|
||||||
|
} finally {
|
||||||
|
setSentimentLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex-1 overflow-auto">
|
<div className="flex-1 overflow-auto">
|
||||||
<div className="p-6">
|
<div className="p-6">
|
||||||
@@ -1584,6 +1797,22 @@ const Analytics: React.FC = () => {
|
|||||||
{/* 平台分布 */}
|
{/* 平台分布 */}
|
||||||
<div className="p-6 bg-white rounded-lg shadow">
|
<div className="p-6 bg-white rounded-lg shadow">
|
||||||
<h3 className="mb-4 text-lg font-medium text-gray-800">平台分布</h3>
|
<h3 className="mb-4 text-lg font-medium text-gray-800">平台分布</h3>
|
||||||
|
{platformLoading ? (
|
||||||
|
<div className="flex flex-col items-center justify-center h-64">
|
||||||
|
<div className="w-12 h-12 border-4 border-blue-500 rounded-full border-t-transparent animate-spin"></div>
|
||||||
|
<p className="mt-4 text-gray-600">加载平台分布数据中...</p>
|
||||||
|
</div>
|
||||||
|
) : platformError ? (
|
||||||
|
<div className="flex flex-col items-center justify-center h-64 p-4 rounded-lg bg-red-50">
|
||||||
|
<AlertTriangle className="w-10 h-10 mb-2 text-red-500" />
|
||||||
|
<p className="text-center text-red-600">{platformError}</p>
|
||||||
|
</div>
|
||||||
|
) : platformData.length === 0 ? (
|
||||||
|
<div className="flex flex-col items-center justify-center h-64 p-4 rounded-lg bg-gray-50">
|
||||||
|
<PieChart className="w-10 h-10 mb-2 text-gray-400" />
|
||||||
|
<p className="text-center text-gray-600">没有找到平台分布数据</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{platformData.map((item, index) => (
|
{platformData.map((item, index) => (
|
||||||
<div key={index}>
|
<div key={index}>
|
||||||
@@ -1591,23 +1820,30 @@ const Analytics: React.FC = () => {
|
|||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
{getPlatformIcon(item.name)}
|
{getPlatformIcon(item.name)}
|
||||||
<span className="ml-2 text-sm font-medium text-gray-700">
|
<span className="ml-2 text-sm font-medium text-gray-700">
|
||||||
{item.name === 'xiaohongshu' ? '小红书' : item.name}
|
{item.name === 'xiaohongshu' ? '小红书' :
|
||||||
|
item.name === 'youtube' ? 'YouTube' :
|
||||||
|
item.name === 'tiktok' ? 'TikTok' :
|
||||||
|
item.name.charAt(0).toUpperCase() + item.name.slice(1)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<span className="mr-2 text-sm text-gray-500">{item.value} 则留言</span>
|
<span className="mr-2 text-sm text-gray-500">{item.value} 则留言</span>
|
||||||
<span className="text-sm font-medium text-gray-700">{item.percentage}%</span>
|
<span className="text-sm font-medium text-gray-700">{item.percentage?.toFixed(1)}%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full h-2 bg-gray-200 rounded-full">
|
<div className="w-full h-2 bg-gray-200 rounded-full">
|
||||||
<div
|
<div
|
||||||
className={`${getPlatformColor(item.name)} h-2 rounded-full transition-all duration-500 ease-in-out`}
|
className={`h-2 rounded-full transition-all duration-500 ease-in-out`}
|
||||||
style={{ width: `${item.percentage}%` }}
|
style={{
|
||||||
|
width: `${item.percentage}%`,
|
||||||
|
backgroundColor: item.color || getPlatformColorHex(item.name)
|
||||||
|
}}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 审核状态分布 */}
|
{/* 审核状态分布 */}
|
||||||
@@ -1656,28 +1892,42 @@ const Analytics: React.FC = () => {
|
|||||||
{/* 情感分析详情 */}
|
{/* 情感分析详情 */}
|
||||||
<div className="p-6 bg-white rounded-lg shadow">
|
<div className="p-6 bg-white rounded-lg shadow">
|
||||||
<h3 className="mb-4 text-lg font-medium text-gray-800">情感分析详情</h3>
|
<h3 className="mb-4 text-lg font-medium text-gray-800">情感分析详情</h3>
|
||||||
|
{sentimentLoading ? (
|
||||||
|
<div className="flex flex-col items-center justify-center h-64">
|
||||||
|
<div className="w-12 h-12 border-4 border-blue-500 rounded-full border-t-transparent animate-spin"></div>
|
||||||
|
<p className="mt-4 text-gray-600">加载情感分析数据中...</p>
|
||||||
|
</div>
|
||||||
|
) : sentimentError ? (
|
||||||
|
<div className="flex flex-col items-center justify-center h-64 p-4 rounded-lg bg-red-50">
|
||||||
|
<AlertTriangle className="w-10 h-10 mb-2 text-red-500" />
|
||||||
|
<p className="text-center text-red-600">{sentimentError}</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
<div className="flex justify-center mb-6">
|
<div className="flex justify-center mb-6">
|
||||||
<div className="relative w-48 h-12 rounded-lg bg-gradient-to-r from-red-500 via-yellow-400 to-green-500">
|
<div className="relative w-48 h-12 rounded-lg bg-gradient-to-r from-red-500 via-yellow-400 to-green-500">
|
||||||
<div
|
<div
|
||||||
className="absolute top-0 w-1 h-full transform -translate-x-1/2 bg-black border-2 border-white rounded-full"
|
className="absolute top-0 w-1 h-full transform -translate-x-1/2 bg-black border-2 border-white rounded-full"
|
||||||
style={{ left: `${sentimentData.positive}%` }}
|
style={{ left: `${sentimentScore * 100}%` }}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-3 gap-4 text-center">
|
<div className="grid grid-cols-3 gap-4 text-center">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-medium text-gray-500">负面</p>
|
<p className="text-sm font-medium text-gray-500">负面</p>
|
||||||
<p className="text-lg font-bold text-red-500">{sentimentData.negative}%</p>
|
<p className="text-lg font-bold text-red-500">{sentimentData.negative.toFixed(1)}%</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-medium text-gray-500">中性</p>
|
<p className="text-sm font-medium text-gray-500">中性</p>
|
||||||
<p className="text-lg font-bold text-yellow-500">{sentimentData.neutral}%</p>
|
<p className="text-lg font-bold text-yellow-500">{sentimentData.neutral.toFixed(1)}%</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-medium text-gray-500">正面</p>
|
<p className="text-sm font-medium text-gray-500">正面</p>
|
||||||
<p className="text-lg font-bold text-green-500">{sentimentData.positive}%</p>
|
<p className="text-lg font-bold text-green-500">{sentimentData.positive.toFixed(1)}%</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 热门文章 */}
|
{/* 热门文章 */}
|
||||||
@@ -1706,3 +1956,28 @@ const Analytics: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default Analytics;
|
export default Analytics;
|
||||||
|
|
||||||
|
// 辅助函数:获取平台的十六进制颜色代码
|
||||||
|
const getPlatformColorHex = (platform: string): string => {
|
||||||
|
const platformLower = platform.toLowerCase();
|
||||||
|
switch (platformLower) {
|
||||||
|
case 'facebook':
|
||||||
|
return '#1877F2';
|
||||||
|
case 'threads':
|
||||||
|
return '#000000';
|
||||||
|
case 'twitter':
|
||||||
|
return '#1DA1F2';
|
||||||
|
case 'instagram':
|
||||||
|
return '#E4405F';
|
||||||
|
case 'linkedin':
|
||||||
|
return '#0A66C2';
|
||||||
|
case 'xiaohongshu':
|
||||||
|
return '#FF0000';
|
||||||
|
case 'youtube':
|
||||||
|
return '#FF0000';
|
||||||
|
case 'tiktok':
|
||||||
|
return '#000000';
|
||||||
|
default:
|
||||||
|
return '#808080'; // 默认灰色
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user