From d48aba50479a9900bbbcd53b8e37d88f06c2a4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=A1=E8=8B=A5?= Date: Mon, 6 Apr 2026 23:12:18 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E4=BB=A5=E6=9C=AC=E5=9C=B0=E4=B8=BA?= =?UTF-8?q?=E5=87=86=E5=90=8C=E6=AD=A5=E6=9C=80=E6=96=B0=E6=94=B9=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 提交当前本地未入库的前后端与发布脚本改动,作为本地主版本基线,用于全量覆盖同步到 GitHub。 Made-with: Cursor --- miniprogram/app.js | 30 +++++++++--- miniprogram/pages/index/index.js | 63 ++++++++++++++++---------- miniprogram/pages/index/index.wxml | 9 +++- miniprogram/pages/settings/settings.js | 4 +- scripts/miniprogram_upload.sh | 4 +- scripts/wechat_miniprogram_release.py | 8 ++-- soul-api/internal/handler/ckb.go | 43 ++++++++++++------ soul-api/internal/handler/db_person.go | 15 ++++-- 8 files changed, 116 insertions(+), 60 deletions(-) diff --git a/miniprogram/app.js b/miniprogram/app.js index 1773762b..74742bf4 100644 --- a/miniprogram/app.js +++ b/miniprogram/app.js @@ -10,16 +10,22 @@ const mpPagePopups = require('./utils/mpPagePopups.js') const DEFAULT_APP_ID = 'wxb8bbb2b10dec74aa' const DEFAULT_MCH_ID = '1318592501' const DEFAULT_WITHDRAW_TMPL_ID = 'u3MbZGPRkrZIk-I7QdpwzFxnO_CeQPaCWF2FkiIablE' -// baseUrl 手动切换(本地端口以 soul-api/.env 的 PORT 为准,当前仓库多为 8080;发版前改回线上) -const API_BASE_URL = 'http://127.0.0.1:8080' -// const API_BASE_URL = 'https://soulapi.quwanzhi.com' -// const API_BASE_URL = 'https://souldev.quwanzhi.com' +// 线上正式域名(真机/体验版/正式版强制使用此地址) +const API_BASE_URL_PROD = 'https://soulapi.quwanzhi.com' +// 本地开发地址(仅开发者工具模拟器生效;真机自动回退 PROD) +const API_BASE_URL_DEV = 'http://127.0.0.1:8080' +// const API_BASE_URL_DEV = 'https://souldev.quwanzhi.com' + +// 运行时自动判断:非开发工具(真机/体验版/正式版)强制用 PROD,避免 localhost 打进上传包导致白屏 +const _isDevTools = (typeof __wxConfig !== 'undefined' && __wxConfig.platform === 'devtools') + || (wx.getSystemInfoSync && wx.getSystemInfoSync().platform === 'devtools') +const API_BASE_URL = _isDevTools ? API_BASE_URL_DEV : API_BASE_URL_PROD const CONFIG_CACHE_KEY = 'mpConfigCacheV1' /** 新用户未完成头像+昵称前,强制留在资料引导(与 avatar-nickname 页配合) */ const PROFILE_GUIDE_REQUIRED_KEY = 'profile_guide_required' // 与上传版本号对齐;设置页展示优先用 wx.getAccountInfoSync().miniProgram.version(正式版),否则用本字段 -const APP_DISPLAY_VERSION = '1.7.2' +const APP_DISPLAY_VERSION = '1.7.3' App({ globalData: { @@ -114,8 +120,20 @@ App({ onLaunch(options) { - // baseUrl 固定取 API_BASE_URL(通过注释切换) this.globalData.baseUrl = API_BASE_URL + if (!_isDevTools && API_BASE_URL.indexOf('127.0.0.1') !== -1) { + console.error('[App] 检测到真机使用 localhost,强制切换为线上地址') + this.globalData.baseUrl = API_BASE_URL_PROD + } + // 体验版/正式版:与上传提审前扫码体验一致,必须走线上正式域名(不依赖其它开关) + try { + const ai = wx.getAccountInfoSync && wx.getAccountInfoSync() + const ev = ai && ai.miniProgram && ai.miniProgram.envVersion + if (ev === 'trial' || ev === 'release') { + this.globalData.baseUrl = API_BASE_URL_PROD + } + } catch (_e) {} + console.log('[App] 运行环境:', _isDevTools ? '开发工具' : '真机/体验版', '| baseUrl:', this.globalData.baseUrl) // 昵称等隐私组件需先授权:input type="nickname" 不会主动触发,需配合 wx.requirePrivacyAuthorize 使用 if (typeof wx.onNeedPrivacyAuthorization === 'function') { wx.onNeedPrivacyAuthorization((resolve) => { diff --git a/miniprogram/pages/index/index.js b/miniprogram/pages/index/index.js index 9b299492..46da6688 100644 --- a/miniprogram/pages/index/index.js +++ b/miniprogram/pages/index/index.js @@ -155,6 +155,8 @@ Page({ // Banner 推荐(优先用 recommended API 第一条,回退 latest-chapters) bannerSection: null, + /** 首屏 Banner 请求完成前为 true;完成后为 false,避免接口全失败时长期显示「加载中」 */ + bannerLoading: true, latestLabel: '最新更新', // 内容概览 @@ -335,6 +337,7 @@ Page({ // 精选推荐 + 最新更新 + 最新列表:顺序以后端为准(recommended=排行榜算法,latest=updated_at) async loadFeaturedAndLatest() { + this.setData({ bannerLoading: true }) try { const tagClassForTag = (tag) => (tag === '热门' ? 'tag-hot' : 'tag-rec') const toSectionFromRanking = (s) => { @@ -429,6 +432,8 @@ Page({ this.setData({ latestChapters, displayLatestChapters: display }) } catch (e) { console.log('[Index] 从服务端加载推荐失败:', e) + } finally { + this.setData({ bannerLoading: false }) } }, @@ -514,35 +519,36 @@ Page({ /** 拉取后台置顶 @人物,合并到首页右上角「链接」区;同时拿到该人的 homeEntryConfig */ async loadHomePinnedPerson() { + let pinnedPerson = null + let override try { const res = await app.request({ url: '/api/miniprogram/ckb/pinned-person', silent: true }) if (res && res.success && res.data && res.data.token) { const name = cleanSingleLineField(res.data.name) || '好友' let av = String(res.data.avatar || '').trim() if (!isSafeImageSrc(av)) av = '' - this.setData({ - homePinnedPerson: { - token: String(res.data.token).trim(), - name, - avatar: av, - homeEntryConfig: res.data.homeEntryConfig || null, - }, - }) + pinnedPerson = { + token: String(res.data.token).trim(), + name, + avatar: av, + homeEntryConfig: res.data.homeEntryConfig || null, + } + if (pinnedPerson.homeEntryConfig) { + override = {} + if (pinnedPerson.homeEntryConfig.linkKaruoReward) override.linkKaruoReward = pinnedPerson.homeEntryConfig.linkKaruoReward + if (pinnedPerson.homeEntryConfig.liveMicSchedule) override.liveMicSchedule = pinnedPerson.homeEntryConfig.liveMicSchedule + } } else { - this.setData({ homePinnedPerson: null }) + pinnedPerson = null } } catch (e) { console.log('[Index] pinned-person:', e) - this.setData({ homePinnedPerson: null }) + pinnedPerson = null } - const pin = (this.data.homePinnedPerson || {}) - const override = {} - if (pin.homeEntryConfig) { - if (pin.homeEntryConfig.linkKaruoReward) override.linkKaruoReward = pin.homeEntryConfig.linkKaruoReward - if (pin.homeEntryConfig.liveMicSchedule) override.liveMicSchedule = pin.homeEntryConfig.liveMicSchedule - } - this._applyHomeMpUi() - this._refreshHomeEntryFlags(Object.keys(override).length ? override : undefined) + this.setData({ homePinnedPerson: pinnedPerson }, () => { + this._applyHomeMpUi() + this._refreshHomeEntryFlags(override) + }) }, async loadFeatureConfig() { @@ -581,13 +587,19 @@ Page({ await this.loadHomePinnedPerson() }, - _refreshHomeEntryFlags() { + _refreshHomeEntryFlags(override) { const audit = !!app.globalData.auditMode - // 优先读置顶超级个体的 per-person 配置,回退到全局 mpUi.homePage - const personCfg = (this.data.homePinnedPerson && this.data.homePinnedPerson.homeEntryConfig) || null + // 有置顶人物时:入口开关严格按该人物配置,不再回退全局,避免“人字拖未开上麦却显示申请上麦”。 + // 无置顶人物时:沿用全局 mpUi.homePage。 + const hasPinned = !!(this.data.homePinnedPerson && this.data.homePinnedPerson.token) + const personCfg = override || ((this.data.homePinnedPerson && this.data.homePinnedPerson.homeEntryConfig) || null) const h = app.globalData.configCache?.mpConfig?.mpUi?.homePage || {} - const rw = (personCfg && personCfg.linkKaruoReward) || h.linkKaruoReward || {} - const schReal = (personCfg && personCfg.liveMicSchedule) || h.liveMicSchedule || {} + const rw = hasPinned + ? ((personCfg && personCfg.linkKaruoReward) || {}) + : (h.linkKaruoReward || {}) + const schReal = hasPinned + ? ((personCfg && personCfg.liveMicSchedule) || {}) + : (h.liveMicSchedule || {}) const rewardEnabled = normCfgBool(rw.enabled) const micEnabled = normCfgBool(schReal.enabled) const inWindow = isNowInMicWindow(schReal.micStart, schReal.micEnd) @@ -648,8 +660,9 @@ Page({ avatar = this.data.mpUiLinkKaruoDisplay || DEFAULT_KARUO_LINK_AVATAR } else if (reward) { show = true; kind = 'reward' - label = String(sch.micButtonText || '申请上麦').trim() || '申请上麦' - emoji = String(sch.micEmoji || '🎤').trim() || '🎤' + const rwUi = this.data.linkKaruoRewardUi || {} + label = String(rwUi.entryButtonText || '支持一下').trim() || '支持一下' + emoji = '' } this.setData({ headerCornerAction: { show, kind, label, emoji, avatar } }) }, diff --git a/miniprogram/pages/index/index.wxml b/miniprogram/pages/index/index.wxml index 9256256f..7ba67e96 100644 --- a/miniprogram/pages/index/index.wxml +++ b/miniprogram/pages/index/index.wxml @@ -47,12 +47,17 @@ -