feat: 小程序阅读记录与资料链路、管理端用户规则、API/VIP/推荐与运营脚本
- miniprogram: reading-records、imageUrl/mpNavigate、多页资料与 VIP 展示调整 - soul-admin: Users/Settings/UserDetailModal、dist 构建产物更新 - soul-api: user/vip/referral/ckb/db、MBTI 头像管理、user_rule_completion、迁移 SQL - .cursor: karuo-party 与飞书文档;.gitignore 忽略 .tmp_skill_bundle Made-with: Cursor
This commit is contained in:
@@ -32,13 +32,13 @@ class ReadingTracker {
|
||||
|
||||
console.log('[ReadingTracker] 初始化追踪:', sectionId)
|
||||
|
||||
// 恢复上次阅读位置
|
||||
this.saveProgressLocal()
|
||||
app.touchRecentSection(sectionId)
|
||||
|
||||
this.restoreLastPosition(sectionId)
|
||||
|
||||
// 开始定期上报(每30秒)
|
||||
this.startProgressReport()
|
||||
|
||||
// 立即上报一次「打开/点击」,确保内容管理后台的「点击」数据有记录(与 reading_progress 表直接捆绑)
|
||||
setTimeout(() => this.reportProgressToServer(false), 0)
|
||||
}
|
||||
|
||||
@@ -177,16 +177,20 @@ class ReadingTracker {
|
||||
this.activeTracker.lastScrollTime = now
|
||||
|
||||
try {
|
||||
const data = {
|
||||
userId,
|
||||
sectionId: this.activeTracker.sectionId,
|
||||
progress: this.activeTracker.maxProgress,
|
||||
duration: this.activeTracker.totalDuration,
|
||||
status: this.activeTracker.isCompleted ? 'completed' : 'reading'
|
||||
}
|
||||
if (this.activeTracker.isCompleted && this.activeTracker.completedAt != null) {
|
||||
const t = this.activeTracker.completedAt
|
||||
data.completedAt = typeof t === 'number' ? new Date(t).toISOString() : String(t)
|
||||
}
|
||||
await app.request('/api/miniprogram/user/reading-progress', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
userId,
|
||||
sectionId: this.activeTracker.sectionId,
|
||||
progress: this.activeTracker.maxProgress,
|
||||
duration: this.activeTracker.totalDuration,
|
||||
status: this.activeTracker.isCompleted ? 'completed' : 'reading',
|
||||
completedAt: this.activeTracker.completedAt
|
||||
}
|
||||
data
|
||||
})
|
||||
|
||||
if (isCompletion) {
|
||||
|
||||
Reference in New Issue
Block a user