feat(miniprogram): 用 karuo-316 替换小程序目录

- 从 github/karuo-316 覆盖 miniprogram/
- 排除 project.private.config.json 与 *.backup

Made-with: Cursor
This commit is contained in:
卡若
2026-03-17 18:25:24 +08:00
parent 982622368a
commit 34f7c7bbdc
34 changed files with 450 additions and 891 deletions

View File

@@ -170,10 +170,10 @@ class ReadingTracker {
const userId = app.globalData.userInfo?.id
if (!userId) return
// 计算本次上报的时长(仅发送增量 delta后端会累加避免重复累加导致阅读分钟数异常
// 计算本次上报的时长
const now = Date.now()
const delta = Math.round((now - this.activeTracker.lastScrollTime) / 1000)
this.activeTracker.totalDuration += delta
const duration = Math.round((now - this.activeTracker.lastScrollTime) / 1000)
this.activeTracker.totalDuration += duration
this.activeTracker.lastScrollTime = now
try {
@@ -183,7 +183,7 @@ class ReadingTracker {
userId,
sectionId: this.activeTracker.sectionId,
progress: this.activeTracker.maxProgress,
duration: Math.max(0, delta),
duration: this.activeTracker.totalDuration,
status: this.activeTracker.isCompleted ? 'completed' : 'reading',
completedAt: this.activeTracker.completedAt
}

View File

@@ -1,7 +1,6 @@
/**
* Soul创业派对 - 用户旅程规则引擎
* 从后端 /api/miniprogram/user-rules 读取启用的规则,按场景触发引导
* 稳定版兼容readCount 用 getReadCount()hasPurchasedFull 用 hasFullBook完善头像跳 avatar-nickname
*
* trigger → scene 映射:
* 注册 → after_login
@@ -86,7 +85,6 @@ function getRuleInfo(rules, triggerName) {
return rules.find(r => r.trigger === triggerName)
}
// 稳定版:跳转 avatar-nickname与 _ensureProfileCompletedAfterLogin 一致)
function checkRule_FillAvatar(rules) {
if (!isRuleEnabled(rules, '注册')) return null
const user = getUserInfo()
@@ -102,7 +100,7 @@ function checkRule_FillAvatar(rules) {
title: info?.title || '完善个人信息',
message: info?.description || '设置头像和昵称,让其他创业者更容易认识你',
action: 'navigate',
target: '/pages/avatar-nickname/avatar-nickname'
target: '/pages/profile-edit/profile-edit'
}
}
@@ -140,12 +138,11 @@ function checkRule_FillProfile(rules) {
}
}
// 稳定版兼容readCount 用 getReadCount()
function checkRule_ShareAfter5Chapters(rules) {
if (!isRuleEnabled(rules, '累计浏览5章节')) return null
const user = getUserInfo()
if (!user.id) return null
const readCount = (typeof app.getReadCount === 'function' ? app.getReadCount() : (app.globalData.readCount || 0))
const readCount = app.globalData.readCount || 0
if (readCount < 5) return null
if (isInCooldown('share_after_5')) return null
setCooldown('share_after_5')
@@ -159,12 +156,11 @@ function checkRule_ShareAfter5Chapters(rules) {
}
}
// 稳定版兼容hasPurchasedFull 用 hasFullBook
function checkRule_FillVipInfo(rules) {
if (!isRuleEnabled(rules, '完成付款')) return null
const user = getUserInfo()
if (!user.id) return null
if (!(app.globalData.hasFullBook || app.globalData.hasPurchasedFull)) return null
if (!app.globalData.hasPurchasedFull) return null
if (user.wechatId && user.address) return null
if (isInCooldown('fill_vip_info')) return null
setCooldown('fill_vip_info')

View File

@@ -9,11 +9,11 @@ const app = getApp()
*/
function trackClick(module, action, target, extra) {
const userId = app.globalData.userInfo?.id || ''
app.request({
url: '/api/miniprogram/track',
if (!userId) return
app.request('/api/miniprogram/track', {
method: 'POST',
data: {
userId: userId || undefined,
userId,
action,
target,
extraData: Object.assign({ module, page: module }, extra || {})

View File

@@ -32,18 +32,6 @@ const formatMoney = (amount, decimals = 2) => {
return Number(amount).toFixed(decimals)
}
/**
* 格式化统计数字≥1万显示 x.xw≥1千显示 x.xk否则原样
* @param {number} n - 原始数字
* @returns {string}
*/
const formatStatNum = n => {
const num = Number(n) || 0
if (num >= 10000) return (num / 10000).toFixed(1).replace(/\.0$/, '') + 'w'
if (num >= 1000) return (num / 1000).toFixed(1).replace(/\.0$/, '') + 'k'
return String(num)
}
// 防抖函数
const debounce = (fn, delay = 300) => {
let timer = null
@@ -187,7 +175,6 @@ module.exports = {
formatTime,
formatDate,
formatMoney,
formatStatNum,
formatNumber,
debounce,
throttle,