init
This commit is contained in:
120
backend/src/controllers/commentsController.ts
Normal file
120
backend/src/controllers/commentsController.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { Context } from 'hono';
|
||||
import supabase from '../utils/supabase';
|
||||
|
||||
export const getComments = async (c: Context) => {
|
||||
try {
|
||||
const { post_id, limit = '10', offset = '0' } = c.req.query();
|
||||
|
||||
let query;
|
||||
|
||||
if (post_id) {
|
||||
// 获取特定帖子的评论
|
||||
query = supabase.rpc('get_comments_for_post', { post_id_param: post_id });
|
||||
} else {
|
||||
// 获取所有评论
|
||||
query = supabase.rpc('get_comments_with_posts');
|
||||
}
|
||||
|
||||
// 应用分页
|
||||
query = query.range(Number(offset), Number(offset) + Number(limit) - 1);
|
||||
|
||||
const { data: comments, error, count } = await query;
|
||||
|
||||
if (error) {
|
||||
return c.json({ error: error.message }, 500);
|
||||
}
|
||||
|
||||
return c.json({
|
||||
comments,
|
||||
count,
|
||||
limit: Number(limit),
|
||||
offset: Number(offset)
|
||||
});
|
||||
} catch (error) {
|
||||
return c.json({ error: 'Internal server error' }, 500);
|
||||
}
|
||||
};
|
||||
|
||||
export const createComment = async (c: Context) => {
|
||||
try {
|
||||
const { post_id, content } = await c.req.json();
|
||||
const user_id = c.get('user')?.id;
|
||||
|
||||
if (!user_id) {
|
||||
return c.json({ error: 'Unauthorized' }, 401);
|
||||
}
|
||||
|
||||
const { data: comment, error } = await supabase
|
||||
.from('comments')
|
||||
.insert({
|
||||
post_id,
|
||||
content,
|
||||
user_id
|
||||
})
|
||||
.select(`
|
||||
comment_id,
|
||||
content,
|
||||
sentiment_score,
|
||||
created_at,
|
||||
updated_at,
|
||||
post_id,
|
||||
user_id
|
||||
`)
|
||||
.single();
|
||||
|
||||
if (error) {
|
||||
return c.json({ error: error.message }, 500);
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
const { data: userProfile, error: userError } = await supabase
|
||||
.from('user_profiles')
|
||||
.select('id, full_name, avatar_url')
|
||||
.eq('id', user_id)
|
||||
.single();
|
||||
|
||||
if (!userError && userProfile) {
|
||||
comment.user_profile = userProfile;
|
||||
}
|
||||
|
||||
return c.json(comment, 201);
|
||||
} catch (error) {
|
||||
return c.json({ error: 'Internal server error' }, 500);
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteComment = async (c: Context) => {
|
||||
try {
|
||||
const { comment_id } = c.req.param();
|
||||
const user_id = c.get('user')?.id;
|
||||
|
||||
if (!user_id) {
|
||||
return c.json({ error: 'Unauthorized' }, 401);
|
||||
}
|
||||
|
||||
// Check if the comment belongs to the user
|
||||
const { data: comment, error: fetchError } = await supabase
|
||||
.from('comments')
|
||||
.select()
|
||||
.eq('comment_id', comment_id)
|
||||
.eq('user_id', user_id)
|
||||
.single();
|
||||
|
||||
if (fetchError || !comment) {
|
||||
return c.json({ error: 'Comment not found or unauthorized' }, 404);
|
||||
}
|
||||
|
||||
const { error: deleteError } = await supabase
|
||||
.from('comments')
|
||||
.delete()
|
||||
.eq('comment_id', comment_id);
|
||||
|
||||
if (deleteError) {
|
||||
return c.json({ error: deleteError.message }, 500);
|
||||
}
|
||||
|
||||
return c.body(null, 204);
|
||||
} catch (error) {
|
||||
return c.json({ error: 'Internal server error' }, 500);
|
||||
}
|
||||
};
|
||||
136
backend/src/controllers/influencersController.ts
Normal file
136
backend/src/controllers/influencersController.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
import { Context } from 'hono';
|
||||
import supabase from '../utils/supabase';
|
||||
|
||||
export const getInfluencers = async (c: Context) => {
|
||||
try {
|
||||
const {
|
||||
platform,
|
||||
limit = '10',
|
||||
offset = '0',
|
||||
min_followers,
|
||||
max_followers,
|
||||
sort_by = 'followers_count',
|
||||
sort_order = 'desc'
|
||||
} = c.req.query();
|
||||
|
||||
let query = supabase
|
||||
.from('influencers')
|
||||
.select(`
|
||||
influencer_id,
|
||||
name,
|
||||
platform,
|
||||
profile_url,
|
||||
followers_count,
|
||||
video_count,
|
||||
platform_count,
|
||||
created_at,
|
||||
updated_at
|
||||
`);
|
||||
|
||||
// Apply filters
|
||||
if (platform) {
|
||||
query = query.eq('platform', platform);
|
||||
}
|
||||
if (min_followers) {
|
||||
query = query.gte('followers_count', Number(min_followers));
|
||||
}
|
||||
if (max_followers) {
|
||||
query = query.lte('followers_count', Number(max_followers));
|
||||
}
|
||||
|
||||
// Apply sorting
|
||||
if (sort_by && ['followers_count', 'video_count', 'created_at'].includes(sort_by)) {
|
||||
query = query.order(sort_by, { ascending: sort_order === 'asc' });
|
||||
}
|
||||
|
||||
// Apply pagination
|
||||
query = query.range(Number(offset), Number(offset) + Number(limit) - 1);
|
||||
|
||||
const { data: influencers, error, count } = await query;
|
||||
|
||||
if (error) {
|
||||
return c.json({ error: error.message }, 500);
|
||||
}
|
||||
|
||||
return c.json({
|
||||
influencers,
|
||||
count,
|
||||
limit: Number(limit),
|
||||
offset: Number(offset)
|
||||
});
|
||||
} catch (error) {
|
||||
return c.json({ error: 'Internal server error' }, 500);
|
||||
}
|
||||
};
|
||||
|
||||
export const getInfluencerById = async (c: Context) => {
|
||||
try {
|
||||
const { influencer_id } = c.req.param();
|
||||
|
||||
const { data: influencer, error } = await supabase
|
||||
.from('influencers')
|
||||
.select(`
|
||||
influencer_id,
|
||||
name,
|
||||
platform,
|
||||
profile_url,
|
||||
followers_count,
|
||||
video_count,
|
||||
platform_count,
|
||||
created_at,
|
||||
updated_at,
|
||||
posts (
|
||||
post_id,
|
||||
title,
|
||||
description,
|
||||
published_at
|
||||
)
|
||||
`)
|
||||
.eq('influencer_id', influencer_id)
|
||||
.single();
|
||||
|
||||
if (error) {
|
||||
return c.json({ error: 'Influencer not found' }, 404);
|
||||
}
|
||||
|
||||
return c.json(influencer);
|
||||
} catch (error) {
|
||||
return c.json({ error: 'Internal server error' }, 500);
|
||||
}
|
||||
};
|
||||
|
||||
export const getInfluencerStats = async (c: Context) => {
|
||||
try {
|
||||
const { platform } = c.req.query();
|
||||
|
||||
let query = supabase
|
||||
.from('influencers')
|
||||
.select('platform, followers_count, video_count');
|
||||
|
||||
if (platform) {
|
||||
query = query.eq('platform', platform);
|
||||
}
|
||||
|
||||
const { data: stats, error } = await query;
|
||||
|
||||
if (error) {
|
||||
return c.json({ error: error.message }, 500);
|
||||
}
|
||||
|
||||
const aggregatedStats = {
|
||||
total_influencers: stats.length,
|
||||
total_followers: stats.reduce((sum: number, item: any) => sum + (item.followers_count || 0), 0),
|
||||
total_videos: stats.reduce((sum: number, item: any) => sum + (item.video_count || 0), 0),
|
||||
average_followers: Math.round(
|
||||
stats.reduce((sum: number, item: any) => sum + (item.followers_count || 0), 0) / (stats.length || 1)
|
||||
),
|
||||
average_videos: Math.round(
|
||||
stats.reduce((sum: number, item: any) => sum + (item.video_count || 0), 0) / (stats.length || 1)
|
||||
)
|
||||
};
|
||||
|
||||
return c.json(aggregatedStats);
|
||||
} catch (error) {
|
||||
return c.json({ error: 'Internal server error' }, 500);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user