Update files
This commit is contained in:
parent
aeae68b39e
commit
d85ebdfe01
|
|
@ -56,6 +56,10 @@ const PostSchema = new mongoose.Schema({
|
|||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isArt: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
likes: [{
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: 'User'
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ const TicketActivitySchema = new mongoose.Schema({
|
|||
type: mongoose.Schema.Types.Mixed,
|
||||
default: {}
|
||||
},
|
||||
artsModerated: { type: Number, default: 0 }, // Количество артов, прошедших модерацию
|
||||
createdAt: {
|
||||
type: Date,
|
||||
default: Date.now
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ router.get('/posts', authenticateModeration, requireModerationAccess, async (req
|
|||
commentsCount: post.comments?.length || 0,
|
||||
likesCount: post.likes?.length || 0,
|
||||
isNSFW: post.isNSFW,
|
||||
isArt: post.isArt,
|
||||
publishedToChannel: post.publishedToChannel,
|
||||
adminNumber: post.adminNumber,
|
||||
editedAt: post.editedAt,
|
||||
|
|
@ -245,7 +246,7 @@ router.delete('/posts/:postId/comments/:commentId', authenticateModeration, requ
|
|||
});
|
||||
|
||||
router.put('/posts/:id', authenticateModeration, requireModerationAccess, async (req, res) => {
|
||||
const { content, hashtags, tags, isNSFW } = req.body;
|
||||
const { content, hashtags, tags, isNSFW, isArt } = req.body;
|
||||
|
||||
const post = await Post.findById(req.params.id).populate('author');
|
||||
if (!post) {
|
||||
|
|
@ -285,6 +286,18 @@ router.put('/posts/:id', authenticateModeration, requireModerationAccess, async
|
|||
post.isNSFW = !!isNSFW;
|
||||
}
|
||||
|
||||
// Обработка метки "арт"
|
||||
const wasArt = post.isArt || false;
|
||||
if (isArt !== undefined) {
|
||||
post.isArt = !!isArt;
|
||||
|
||||
// Если арт только что помечен (было false, стало true), начислить билеты
|
||||
if (!wasArt && post.isArt && post.author) {
|
||||
const { awardArtModeration } = require('../utils/tickets');
|
||||
await awardArtModeration(post.author._id);
|
||||
}
|
||||
}
|
||||
|
||||
post.editedAt = new Date();
|
||||
await post.save();
|
||||
|
||||
|
|
@ -312,6 +325,7 @@ router.put('/posts/:id', authenticateModeration, requireModerationAccess, async
|
|||
tags: post.tags,
|
||||
images: post.images,
|
||||
isNSFW: post.isNSFW,
|
||||
isArt: post.isArt,
|
||||
publishedToChannel: post.publishedToChannel,
|
||||
adminNumber: post.adminNumber,
|
||||
editedAt: post.editedAt,
|
||||
|
|
|
|||
|
|
@ -205,6 +205,55 @@ async function awardArtComment(authorId, commenterId, postId) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Начисляет билеты за арт, прошедший модерацию
|
||||
*/
|
||||
async function awardArtModeration(userId) {
|
||||
// Проверяем лимиты: 1 арт в день / 5 в неделю
|
||||
const { getMoscowStartOfDay } = require('./moscowTime');
|
||||
const today = getMoscowStartOfDay();
|
||||
const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
|
||||
|
||||
const activity = await TicketActivity.getOrCreateToday(userId);
|
||||
|
||||
// Проверка лимита: 1 арт в день
|
||||
const todayArts = activity.artsModerated || 0;
|
||||
if (todayArts >= 1) {
|
||||
console.log(`[Tickets ${formatMoscowTime()}] Лимит артов на сегодня достигнут для пользователя ${userId}`);
|
||||
return { success: false, reason: 'daily_limit_reached' };
|
||||
}
|
||||
|
||||
// Проверка лимита: 5 артов в неделю
|
||||
const TicketActivityModel = require('../models/TicketActivity');
|
||||
const weekActivities = await TicketActivityModel.find({
|
||||
user: userId,
|
||||
date: { $gte: weekAgo }
|
||||
});
|
||||
|
||||
const weekArtsCount = weekActivities.reduce((sum, act) => {
|
||||
return sum + (act.artsModerated || 0);
|
||||
}, 0);
|
||||
|
||||
if (weekArtsCount >= 5) {
|
||||
console.log(`[Tickets ${formatMoscowTime()}] Лимит артов на неделю достигнут для пользователя ${userId}`);
|
||||
return { success: false, reason: 'weekly_limit_reached' };
|
||||
}
|
||||
|
||||
// Начислить билеты
|
||||
if (!activity.artsModerated) {
|
||||
activity.artsModerated = 0;
|
||||
}
|
||||
activity.artsModerated += 1;
|
||||
await activity.save();
|
||||
|
||||
await User.findByIdAndUpdate(userId, {
|
||||
$inc: { tickets: 40 }
|
||||
});
|
||||
|
||||
console.log(`[Tickets ${formatMoscowTime()}] Начислено 40 билетов пользователю ${userId} за арт, прошедший модерацию`);
|
||||
return { success: true, points: 40 };
|
||||
}
|
||||
|
||||
/**
|
||||
* Списывает билеты за действие (лайк/комментарий) с удаленным постом
|
||||
*/
|
||||
|
|
@ -373,6 +422,7 @@ module.exports = {
|
|||
awardReferral,
|
||||
awardArtLike,
|
||||
awardArtComment,
|
||||
awardArtModeration,
|
||||
deductPostCreation,
|
||||
deductPostDeletion,
|
||||
deductAction,
|
||||
|
|
|
|||
|
|
@ -422,6 +422,12 @@ export default function App() {
|
|||
loadUsers();
|
||||
};
|
||||
|
||||
const handleToggleArt = async (post) => {
|
||||
const newIsArt = !post.isArt;
|
||||
await updatePost(post.id, { isArt: newIsArt });
|
||||
loadPosts();
|
||||
};
|
||||
|
||||
const handleOpenComments = async (postId) => {
|
||||
setCommentsLoading(true);
|
||||
try {
|
||||
|
|
@ -631,6 +637,13 @@ export default function App() {
|
|||
<Edit size={16} />
|
||||
Редактировать
|
||||
</button>
|
||||
<button
|
||||
className={`btn ${post.isArt ? 'active' : ''}`}
|
||||
onClick={() => handleToggleArt(post)}
|
||||
style={post.isArt ? { backgroundColor: '#4CAF50', color: 'white' } : {}}
|
||||
>
|
||||
🎨 Арт
|
||||
</button>
|
||||
<button className="btn danger" onClick={() => handlePostDelete(post.id)}>
|
||||
<Trash2 size={16} />
|
||||
Удалить
|
||||
|
|
|
|||
Loading…
Reference in New Issue