fix(mp): 二轮审计修复 — ScrollView嵌套/InputField重建/markdown分组/BLE上限/缓存清理

CRITICAL: ai-report/list PageShell scroll=false 修复双重滚动冲突
HIGH: dialysis/create InputField 提取为独立组件避免 render 销毁重建
MEDIUM: markdownToHtml 连续<li>合并到单个<ul>
MEDIUM: 咨询详情页图片添加 lazyLoad
MEDIUM: BLEManager readings 添加 MAX_LIVE_READINGS=200 上限
MEDIUM: DataBuffer trimToMax 时重建 seenKeys 保持一致性
MEDIUM: auth.ts logout 清理模块级缓存变量
LOW: request.ts safeReLaunch 添加 console.warn + doRefresh 死锁警告注释
This commit is contained in:
iven
2026-05-17 18:54:27 +08:00
parent 66aef532fa
commit fcce2f5c51
9 changed files with 59 additions and 33 deletions

View File

@@ -16,6 +16,8 @@ const DEFAULT_CONFIG: BLEManagerConfig = {
retryCount: 3,
};
const MAX_LIVE_READINGS = 200;
export class BLEManager {
private adapters: DeviceAdapter[] = [];
private connection: BLEConnection | null = null;
@@ -193,7 +195,10 @@ export class BLEManager {
res.value,
);
if (newReadings.length > 0) {
this.readings = [...this.readings, ...newReadings];
const combined = [...this.readings, ...newReadings];
this.readings = combined.length > MAX_LIVE_READINGS
? combined.slice(-MAX_LIVE_READINGS)
: combined;
this.dataBuffer.push(newReadings);
this.onReadings?.(newReadings);
}

View File

@@ -132,6 +132,13 @@ export class DataBuffer {
const excess = total - this.config.maxTotal;
this.buckets[0] = this.buckets[0].slice(excess);
}
// 重建 seenKeys 与实际数据一致
this.seenKeys.clear();
for (const bucket of this.buckets) {
for (const r of bucket) {
this.seenKeys.add(this.dedupeKey(r));
}
}
}
private persistCurrentBucket(): void {

View File

@@ -185,6 +185,7 @@ async function tryRefreshToken(): Promise<boolean> {
return refreshPromise;
}
// 直接调用 Taro.request() 而非 request(),避免 ConcurrencyLimiter 死锁
async function doRefresh(): Promise<boolean> {
const refreshToken = secureGet('refresh_token');
if (!refreshToken) return false;
@@ -227,7 +228,9 @@ let reLaunchPromise: Promise<void> | null = null;
function safeReLaunch(url: string): void {
if (reLaunchPromise) return;
reLaunchPromise = Taro.reLaunch({ url }).then(() => {}, () => {}).then(() => {
reLaunchPromise = Taro.reLaunch({ url }).then(() => {}, (err) => {
console.warn('[request] reLaunch failed:', err);
}).then(() => {
setTimeout(() => { reLaunchPromise = null; }, 2000);
});
}