开发机迁移

This commit is contained in:
Neo
2026-04-10 06:24:13 +08:00
parent f65c1d038b
commit 79d3c2e97e
50 changed files with 1565 additions and 318 deletions

View File

@@ -162,6 +162,8 @@ Page({
_lastScrollTop: 0,
_scrollAcc: 0,
_scrollDir: null as 'up' | 'down' | null,
/** 请求代数计数器:切换筛选时递增,旧请求的响应到达后对比丢弃 */
_loadGeneration: 0,
onLoad() {
this.loadData()
@@ -181,6 +183,7 @@ Page({
},
onPullDownRefresh() {
this._loadGeneration++
this.setData({ currentPage: 1, hasMore: true, coaches: [], allCoaches: [] })
this.loadData()
setTimeout(() => wx.stopPullDownRefresh(), 500)
@@ -219,7 +222,9 @@ Page({
// CHANGE 2026-03-28 | P4 联调:替换 Mock 为真实 API 调用
// CHANGE 2026-03-29 | 懒加载:支持分页追加
// CHANGE 2026-04-08 | 竞态修复:用 _loadGeneration 丢弃过时响应
async loadData() {
const gen = this._loadGeneration
const page = this.data.currentPage
const isFirstPage = page === 1
@@ -239,6 +244,8 @@ Page({
page,
pageSize: this.data.pageSize,
})
// 竞态保护:响应到达时代数已变(用户切了筛选),丢弃本次结果
if (gen !== this._loadGeneration) return
const items = res.items
if (isFirstPage && (!items || items.length === 0)) {
this.setData({ pageState: 'empty', totalCount: 0, hasMore: false })
@@ -318,6 +325,7 @@ Page({
onSortChange(e: WechatMiniprogram.CustomEvent<{ value: string }>) {
const val = e.detail.value
this._loadGeneration++
this.setData({
selectedSort: val,
dimType: SORT_TO_DIM[val] || 'perf',
@@ -327,11 +335,13 @@ Page({
},
onSkillChange(e: WechatMiniprogram.CustomEvent<{ value: string }>) {
this._loadGeneration++
this.setData({ selectedSkill: e.detail.value, currentPage: 1, hasMore: true, coaches: [], allCoaches: [] })
this.loadData()
},
onTimeChange(e: WechatMiniprogram.CustomEvent<{ value: string }>) {
this._loadGeneration++
this.setData({ selectedTime: e.detail.value, currentPage: 1, hasMore: true, coaches: [], allCoaches: [] })
this.loadData()
},

View File

@@ -33,7 +33,7 @@ const DIMENSION_OPTIONS = [
{ value: 'recent', text: '最近到店' },
{ value: 'spend60', text: '最高消费 近60天' },
{ value: 'freq60', text: '最频繁 近60天' },
{ value: 'loyal', text: '最专一 近60天' },
{ value: 'loyal', text: '最专一 近90天' },
]
// CHANGE 2026-03-28 | P9 修复value 改为数据库 category_code与后端枚举一致。
@@ -200,6 +200,8 @@ Page({
_lastScrollTop: 0,
_scrollAcc: 0,
_scrollDir: null as 'up' | 'down' | null,
/** 请求代数计数器:切换维度/项目时递增,旧请求的响应到达后对比丢弃 */
_loadGeneration: 0,
onLoad() {
this.loadData()
@@ -219,6 +221,7 @@ Page({
},
onPullDownRefresh() {
this._loadGeneration++
this.setData({ currentPage: 1, hasMore: true, customers: [], allCustomers: [] })
this.loadData()
setTimeout(() => wx.stopPullDownRefresh(), 500)
@@ -257,7 +260,9 @@ Page({
// CHANGE 2026-03-28 | P5 联调:替换 Mock 为真实 API 调用
// CHANGE 2026-03-29 | 懒加载:支持分页追加
// CHANGE 2026-04-08 | 竞态修复:用 _loadGeneration 丢弃过时响应
async loadData() {
const gen = this._loadGeneration
const page = this.data.currentPage
const isFirstPage = page === 1
@@ -276,6 +281,8 @@ Page({
page,
pageSize: this.data.pageSize,
})
// 竞态保护:响应到达时代数已变(用户切了维度/项目),丢弃本次结果
if (gen !== this._loadGeneration) return
const items = res.items
if (isFirstPage && (!items || items.length === 0)) {
this.setData({ pageState: 'empty', totalCount: 0, hasMore: false })
@@ -348,6 +355,7 @@ Page({
onDimensionChange(e: WechatMiniprogram.CustomEvent<{ value: string }>) {
const val = e.detail.value
this._loadGeneration++
this.setData({
selectedDimension: val,
dimType: DIMENSION_TO_DIM[val] || 'recall',
@@ -357,6 +365,7 @@ Page({
},
onProjectChange(e: WechatMiniprogram.CustomEvent<{ value: string }>) {
this._loadGeneration++
this.setData({ selectedProject: e.detail.value, currentPage: 1, hasMore: true, customers: [], allCustomers: [] })
this.loadData()
},

View File

@@ -165,7 +165,7 @@
<text class="grid-val grid-val--lg">{{fmt.money(item.spend30d)}}</text>
</view>
<view class="grid-cell">
<text class="grid-label">月均到店</text>
<text class="grid-label">近30天到店</text>
<text class="grid-val">{{fmt.count(item.avgVisits, '次')}}</text>
</view>
<view class="grid-cell">
@@ -201,7 +201,7 @@
<text class="grid-val">{{fmt.safe(item.lastRecharge)}}</text>
</view>
<view class="grid-cell">
<text class="grid-label">充值</text>
<text class="grid-label">累计充值</text>
<text class="grid-val grid-val--success">{{fmt.money(item.rechargeAmount)}}</text>
</view>
<view class="grid-cell">

View File

@@ -1248,7 +1248,7 @@ AI_CHANGELOG
/* CHANGE 2026-03-14 | intent: H5 gap-1=4px → spec p-1=8rpx */
.coach-fin-header {
display: grid;
grid-template-columns: 1fr 1.2fr 1.2fr 1fr;
grid-template-columns: 1fr 1.5fr 1.5fr 1fr;
gap: 8rpx;
padding: 14rpx 30rpx;
background: #f0f0f0;
@@ -1276,7 +1276,7 @@ AI_CHANGELOG
/* CHANGE 2026-03-14 | intent: H5 gap-1=4px → spec p-1=8rpx基础行 py-2=14rpx */
.coach-fin-row {
display: grid;
grid-template-columns: 1fr 1.2fr 1.2fr 1fr;
grid-template-columns: 1fr 1.5fr 1.5fr 1fr;
gap: 8rpx;
padding: 14rpx 30rpx;
border-bottom: 2rpx solid #f3f3f3;
@@ -1306,7 +1306,7 @@ AI_CHANGELOG
/* CHANGE 2026-03-13 | intent: 校对 H5 coach-fin-bold fontSize:14px→24rpx(87.5%) */
.coach-fin-bold {
font-size: 26rpx;
font-size: 30rpx;
line-height: 36rpx;
font-weight: 600;
color: #242424;