141 lines
3.6 KiB
TypeScript
141 lines
3.6 KiB
TypeScript
/**
|
|
* 阅读进度上报接口
|
|
* POST /api/user/reading-progress
|
|
*
|
|
* 接收小程序上报的阅读进度,用于数据分析和断点续读
|
|
*/
|
|
|
|
import { NextRequest, NextResponse } from 'next/server'
|
|
import { query } from '@/lib/db'
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const body = await request.json()
|
|
const { userId, sectionId, progress, duration, status, completedAt } = body
|
|
|
|
// 参数校验
|
|
if (!userId || !sectionId) {
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: '缺少必要参数'
|
|
}, { status: 400 })
|
|
}
|
|
|
|
// 查询是否已有记录
|
|
const existingRows = await query(`
|
|
SELECT id, progress, duration, status, first_open_at
|
|
FROM reading_progress
|
|
WHERE user_id = ? AND section_id = ?
|
|
`, [userId, sectionId]) as any[]
|
|
|
|
const now = new Date()
|
|
|
|
if (existingRows.length > 0) {
|
|
// 更新已有记录
|
|
const existing = existingRows[0]
|
|
|
|
// 只更新更大的进度
|
|
const newProgress = Math.max(existing.progress || 0, progress || 0)
|
|
const newDuration = (existing.duration || 0) + (duration || 0)
|
|
const newStatus = status || existing.status || 'reading'
|
|
|
|
await query(`
|
|
UPDATE reading_progress
|
|
SET
|
|
progress = ?,
|
|
duration = ?,
|
|
status = ?,
|
|
completed_at = ?,
|
|
last_open_at = ?,
|
|
updated_at = ?
|
|
WHERE user_id = ? AND section_id = ?
|
|
`, [
|
|
newProgress,
|
|
newDuration,
|
|
newStatus,
|
|
completedAt ? new Date(completedAt) : existing.completed_at,
|
|
now,
|
|
now,
|
|
userId,
|
|
sectionId
|
|
])
|
|
|
|
console.log('[ReadingProgress] 更新进度:', { userId, sectionId, progress: newProgress, duration: newDuration })
|
|
} else {
|
|
// 插入新记录
|
|
await query(`
|
|
INSERT INTO reading_progress
|
|
(user_id, section_id, progress, duration, status, completed_at, first_open_at, last_open_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
`, [
|
|
userId,
|
|
sectionId,
|
|
progress || 0,
|
|
duration || 0,
|
|
status || 'reading',
|
|
completedAt ? new Date(completedAt) : null,
|
|
now,
|
|
now
|
|
])
|
|
|
|
console.log('[ReadingProgress] 新增进度:', { userId, sectionId, progress, duration })
|
|
}
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
message: '进度已保存'
|
|
})
|
|
|
|
} catch (error) {
|
|
console.error('[ReadingProgress] 保存失败:', error)
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: '保存进度失败'
|
|
}, { status: 500 })
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 查询用户的阅读进度列表
|
|
* GET /api/user/reading-progress?userId=xxx
|
|
*/
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
const { searchParams } = new URL(request.url)
|
|
const userId = searchParams.get('userId')
|
|
|
|
if (!userId) {
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: '缺少 userId 参数'
|
|
}, { status: 400 })
|
|
}
|
|
|
|
const rows = await query(`
|
|
SELECT
|
|
section_id,
|
|
progress,
|
|
duration,
|
|
status,
|
|
completed_at,
|
|
first_open_at,
|
|
last_open_at
|
|
FROM reading_progress
|
|
WHERE user_id = ?
|
|
ORDER BY last_open_at DESC
|
|
`, [userId]) as any[]
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
data: rows
|
|
})
|
|
|
|
} catch (error) {
|
|
console.error('[ReadingProgress] 查询失败:', error)
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: '查询进度失败'
|
|
}, { status: 500 })
|
|
}
|
|
}
|