|
|
@@ -106,10 +106,22 @@ router.post(
|
|
|
const workId = item.workId ?? item.work_id;
|
|
|
const recordDateStr = item.recordDate ?? item.record_date ?? '';
|
|
|
const recordDate = recordDateStr ? new Date(recordDateStr) : new Date();
|
|
|
- recordDate.setHours(0, 0, 0, 0);
|
|
|
+ // 使用中国时区标准化日期(与 WorkDayStatisticsService 一致)
|
|
|
+ const formatter = new Intl.DateTimeFormat('en-CA', {
|
|
|
+ timeZone: 'Asia/Shanghai',
|
|
|
+ year: 'numeric',
|
|
|
+ month: '2-digit',
|
|
|
+ day: '2-digit',
|
|
|
+ });
|
|
|
+ const parts = formatter.formatToParts(recordDate);
|
|
|
+ const get = (type: string) => parts.find((p) => p.type === type)?.value ?? '0';
|
|
|
+ const y = parseInt(get('year'), 10);
|
|
|
+ const m = parseInt(get('month'), 10) - 1;
|
|
|
+ const d = parseInt(get('day'), 10);
|
|
|
+ const normalizedDate = new Date(Date.UTC(y, m, d, 0, 0, 0, 0));
|
|
|
return {
|
|
|
workId: Number(workId),
|
|
|
- recordDate,
|
|
|
+ recordDate: normalizedDate,
|
|
|
playCount: item.playCount ?? item.play_count ?? 0,
|
|
|
exposureCount: item.exposureCount ?? item.exposure_count ?? 0,
|
|
|
likeCount: item.likeCount ?? item.like_count ?? 0,
|
|
|
@@ -275,29 +287,29 @@ router.post(
|
|
|
|
|
|
const workRepository = AppDataSource.getRepository(Work);
|
|
|
let updated = 0;
|
|
|
- for (const item of updates) {
|
|
|
- const patch: Partial<{
|
|
|
- yesterdayPlayCount: number;
|
|
|
- yesterdayLikeCount: number;
|
|
|
- yesterdayRecommendCount: number;
|
|
|
- yesterdayCommentCount: number;
|
|
|
- yesterdayShareCount: number;
|
|
|
- yesterdayFollowCount: number;
|
|
|
- yesterdayCompletionRate: string;
|
|
|
- yesterdayAvgWatchDuration: string;
|
|
|
- }> = {};
|
|
|
- if (item.yesterday_play_count !== undefined) patch.yesterdayPlayCount = item.yesterday_play_count;
|
|
|
- if (item.yesterday_like_count !== undefined) patch.yesterdayLikeCount = item.yesterday_like_count;
|
|
|
- if (item.yesterday_recommend_count !== undefined) patch.yesterdayRecommendCount = item.yesterday_recommend_count;
|
|
|
- if (item.yesterday_comment_count !== undefined) patch.yesterdayCommentCount = item.yesterday_comment_count;
|
|
|
- if (item.yesterday_share_count !== undefined) patch.yesterdayShareCount = item.yesterday_share_count;
|
|
|
- if (item.yesterday_follow_count !== undefined) patch.yesterdayFollowCount = item.yesterday_follow_count;
|
|
|
- if (item.yesterday_completion_rate !== undefined) patch.yesterdayCompletionRate = String(item.yesterday_completion_rate);
|
|
|
- if (item.yesterday_avg_watch_duration !== undefined) patch.yesterdayAvgWatchDuration = String(item.yesterday_avg_watch_duration);
|
|
|
- if (Object.keys(patch).length === 0) continue;
|
|
|
-
|
|
|
- const result = await workRepository.update(item.work_id, patch);
|
|
|
- if (result.affected && result.affected > 0) updated += result.affected;
|
|
|
+ // 并行批量更新(每批 20 条,减少串行等待)
|
|
|
+ const BATCH_SIZE = 20;
|
|
|
+ for (let i = 0; i < updates.length; i += BATCH_SIZE) {
|
|
|
+ const batch = updates.slice(i, i + BATCH_SIZE);
|
|
|
+ const results = await Promise.allSettled(
|
|
|
+ batch.map(async (item) => {
|
|
|
+ const patch: Record<string, unknown> = {};
|
|
|
+ if (item.yesterday_play_count !== undefined) patch.yesterdayPlayCount = item.yesterday_play_count;
|
|
|
+ if (item.yesterday_like_count !== undefined) patch.yesterdayLikeCount = item.yesterday_like_count;
|
|
|
+ if (item.yesterday_recommend_count !== undefined) patch.yesterdayRecommendCount = item.yesterday_recommend_count;
|
|
|
+ if (item.yesterday_comment_count !== undefined) patch.yesterdayCommentCount = item.yesterday_comment_count;
|
|
|
+ if (item.yesterday_share_count !== undefined) patch.yesterdayShareCount = item.yesterday_share_count;
|
|
|
+ if (item.yesterday_follow_count !== undefined) patch.yesterdayFollowCount = item.yesterday_follow_count;
|
|
|
+ if (item.yesterday_completion_rate !== undefined) patch.yesterdayCompletionRate = String(item.yesterday_completion_rate);
|
|
|
+ if (item.yesterday_avg_watch_duration !== undefined) patch.yesterdayAvgWatchDuration = String(item.yesterday_avg_watch_duration);
|
|
|
+ if (Object.keys(patch).length === 0) return 0;
|
|
|
+ const result = await workRepository.update(item.work_id, patch);
|
|
|
+ return result.affected || 0;
|
|
|
+ })
|
|
|
+ );
|
|
|
+ for (const r of results) {
|
|
|
+ if (r.status === 'fulfilled') updated += r.value;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
res.json({
|