diff --git a/components/AppNavbar.vue b/components/AppNavbar.vue
index 9e33222..415a4f4 100644
--- a/components/AppNavbar.vue
+++ b/components/AppNavbar.vue
@@ -27,21 +27,41 @@ export default {
},
data() {
return {
- currentPages: []
+ currentPages: [],
+ // 状态栏高度只在挂载时取一次:getSafeTop 在 render 中被调用,
+ // 每次都同步读系统信息会反复触发 wx.getSystemInfoSync 废弃告警。
+ safeTop: 0
}
},
methods: {
getSafeTop() {
- const systemInfo = uni.getSystemInfoSync()
- return systemInfo.statusBarHeight
+ return this.safeTop
},
back(){
if (this.currentPages.length === 1) uni.switchTab({url: '/pages/index/index'})
else uni.navigateBack()
+ },
+ // 优先用新接口,取不到时回退旧接口,避免旧接口的废弃告警
+ readSafeTop() {
+ try {
+ if (uni.getWindowInfo) {
+ const info = uni.getWindowInfo()
+ if (info && info.statusBarHeight !== undefined) return info.statusBarHeight
+ }
+ } catch (error) {
+ // ignore:新接口不可用时走下面的回退
+ }
+ try {
+ const systemInfo = uni.getSystemInfoSync()
+ return (systemInfo && systemInfo.statusBarHeight) || 0
+ } catch (error) {
+ return 0
+ }
}
},
mounted() {
this.currentPages = getCurrentPages()
+ this.safeTop = this.readSafeTop()
}
}
diff --git a/packageUser/self-report/records.vue b/packageUser/self-report/records.vue
index 678351e..02423c6 100644
--- a/packageUser/self-report/records.vue
+++ b/packageUser/self-report/records.vue
@@ -61,7 +61,7 @@
{{ statusText(item.status) }}
-
+
活动时间
{{ item.activityTime || '-' }}
@@ -69,7 +69,7 @@
巡店门店数
{{ item.storeCount || 0 }}家
-
+
评分
{{ item.rating || '-' }}星
@@ -88,7 +88,7 @@
-
+
暂无巡店记录
@@ -246,6 +246,8 @@ export default {
],
activeStatus: 'all',
records: [],
+ // 列表请求自增序号:切 tab 会连发请求且响应顺序不保证,只认最后一次,丢弃过期响应
+ listRequestId: 0,
loading: false,
chainLoading: false,
showChainPicker: false,
@@ -336,19 +338,30 @@ export default {
])
},
async fetchList() {
+ const requestId = ++this.listRequestId
+ const type = this.activeType
this.loading = true
try {
- const req = this.activeType === 'visit' ? visitReportUserListReq : selfReportUserListReq
+ const req = type === 'visit' ? visitReportUserListReq : selfReportUserListReq
const {data} = await req({})
- this.records = this.unwrapList(data)
+ // 响应顺序不保证:切 tab 后返回的旧响应直接丢弃,避免另一类型的数据盖进当前 tab
+ if (requestId !== this.listRequestId) return
+ this.records = this.unwrapList(data).map(item => {
+ if (!item || typeof item !== 'object') return item
+ // 类型钉在记录上:后续归一化/筛选/重新提交都以它为准,不再依赖当前 tab
+ return Object.assign({}, item, {reportType: type})
+ })
} catch (error) {
+ if (requestId !== this.listRequestId) return
this.records = []
uni.showToast({
title: '记录加载失败',
icon: 'none'
})
} finally {
- this.loading = false
+ if (requestId === this.listRequestId) {
+ this.loading = false
+ }
}
},
async fetchChainList() {
@@ -368,8 +381,13 @@ export default {
this.chainLoading = false
}
},
+ // 记录所属填报类型:优先取记录自带的 reportType,历史/异常数据回退当前 tab
+ recordType(item) {
+ const type = item && item.reportType
+ return type === 'visit' || type === 'store' ? type : this.activeType
+ },
normalizeRecord(item = {}) {
- if (this.activeType === 'visit') {
+ if (this.recordType(item) === 'visit') {
return this.normalizeVisitRecord(item)
}
const createRaw = item.createTime || item.createdAt || item.date || ''
@@ -381,6 +399,7 @@ export default {
const summary = typeof summaryRaw === 'string' ? summaryRaw : JSON.stringify(summaryRaw || '')
return {
id: item.id,
+ reportType: 'store',
merchantId: item.merchantId || item.merchant_id || '',
merchantName: item.merchantName || item.merchant_name || '',
chainName: item.chainName || item.chain_name || '-',
@@ -419,6 +438,7 @@ export default {
}))
return {
id: item.id,
+ reportType: 'visit',
merchantId: '',
merchantName: '',
chainName: '-',
@@ -509,13 +529,13 @@ export default {
matchesItemChain(item) {
const selectedId = this.filterForm.chainId
if (selectedId === '' || selectedId === null || selectedId === undefined) return true
- if (this.activeType === 'visit') {
+ if (this.recordType(item) === 'visit') {
return (item.storeRows || []).some(store => this.matchesSelectedChain('', store.chainName, selectedId))
}
return this.matchesSelectedChain(item.chainIdNormalized, item.chainName, selectedId)
},
matchesItemKeyword(item, keyword) {
- if (this.activeType === 'visit') {
+ if (this.recordType(item) === 'visit') {
return (item.storeRows || []).some(store => String(store.merchantName || '').toLowerCase().includes(keyword))
}
return String(item.merchantName || '').toLowerCase().includes(keyword)
@@ -584,13 +604,14 @@ export default {
},
handleResubmit(item) {
if (!item || item.id === undefined || item.id === null) return
- const url = this.activeType === 'visit'
+ // 按记录自带的类型跳转,不用当前 tab —— tab 与实际数据错位时也不会进错表单
+ const url = this.recordType(item) === 'visit'
? `/packageUser/self-report/visit?id=${item.id}&mode=resubmit`
: `/packageUser/self-report/create?id=${item.id}&mode=resubmit`
uni.navigateTo({url})
},
cardTitle(item) {
- if (this.activeType === 'visit') {
+ if (this.recordType(item) === 'visit') {
const names = (item.storeRows || [])
.map(store => store.merchantName)
.filter(Boolean)
@@ -602,7 +623,7 @@ export default {
return item.merchantName || '-'
},
cardSubTitle(item) {
- if (this.activeType === 'visit') return ''
+ if (this.recordType(item) === 'visit') return ''
return item.chainName && item.chainName !== '-' ? `连锁:${item.chainName}` : ''
},
changeType(value) {
diff --git a/packageUser/self-report/select.vue b/packageUser/self-report/select.vue
index 694dcdd..3fef2da 100644
--- a/packageUser/self-report/select.vue
+++ b/packageUser/self-report/select.vue
@@ -82,10 +82,26 @@ export default {
}
},
onLoad() {
- const systemInfo = uni.getSystemInfoSync()
- this.statusBarHeight = systemInfo.statusBarHeight || 0
+ this.statusBarHeight = this.readStatusBarHeight()
},
methods: {
+ // 优先用新接口,取不到时回退旧接口,避免 getSystemInfoSync 的废弃告警
+ readStatusBarHeight() {
+ try {
+ if (uni.getWindowInfo) {
+ const info = uni.getWindowInfo()
+ if (info && info.statusBarHeight !== undefined) return info.statusBarHeight || 0
+ }
+ } catch (error) {
+ // ignore:新接口不可用时走下面的回退
+ }
+ try {
+ const systemInfo = uni.getSystemInfoSync()
+ return (systemInfo && systemInfo.statusBarHeight) || 0
+ } catch (error) {
+ return 0
+ }
+ },
back() {
if (getCurrentPages().length === 1) {
uni.switchTab({url: '/pages/index/index'})
diff --git a/packageUser/self-report/visit.vue b/packageUser/self-report/visit.vue
index 1e17d12..678cc3e 100644
--- a/packageUser/self-report/visit.vue
+++ b/packageUser/self-report/visit.vue
@@ -8,7 +8,7 @@
暂无巡店记录,请点击下方「新增巡店」
-
+
巡店{{ idx + 1 }}
@@ -70,7 +70,7 @@
-
+
x
@@ -117,7 +117,7 @@
@change="onChainPickerChange"
>
-
+
{{ item.text }}
@@ -148,7 +148,7 @@
@change="onMerchantPickerChange"
>
-
+
{{ item.text }}
@@ -233,6 +233,8 @@ export default {
created() {
// 门店明细挂实例上而非 data:data 里的一切都会进页面 data 树并被 setData 序列化。
this.merchantStore = []
+ // 巡店项 key 的自增种子,同样放实例上,不必进 data 树
+ this.storeKeySeed = 0
},
async onLoad(options = {}) {
const id = options && options.id !== undefined && options.id !== null ? String(options.id).trim() : ''
@@ -523,8 +525,23 @@ export default {
},
// ---------- 巡店列表 ----------
+ // wx:key 需要稳定且互不相同的标识;用自增序号,避免同一份数据里出现重复 key
+ buildStoreKey() {
+ this.storeKeySeed = (this.storeKeySeed || 0) + 1
+ return `store_${this.storeKeySeed}`
+ },
+ // 给数组里缺失 _rowKey 的项补齐(重提加载的旧数据没有该字段)
+ ensureStoreKeys(list) {
+ return (Array.isArray(list) ? list : []).map(item => {
+ if (item && item._rowKey) return item
+ return Object.assign({}, item, {_rowKey: this.buildStoreKey()})
+ })
+ },
createStoreItem() {
return {
+ // 小程序 wx:key 只认属性名,模板字面量会被编译丢弃;
+ // 该字段同时让增删巡店时的节点复用稳定(删除靠后的项不会让前面的项重建)
+ _rowKey: this.buildStoreKey(),
visitTime: this.formatDateTime(new Date()),
merchantId: '',
merchantName: '',
@@ -729,7 +746,7 @@ export default {
const nextForm = Object.assign(this.buildForm(), this.cloneValue(draft.form || {}))
this.form = nextForm
const storeList = Array.isArray(draft.storeList) ? draft.storeList : []
- this.storeList = storeList.map(item => this.normalizeStoreItem(item))
+ this.storeList = this.ensureStoreKeys(storeList.map(item => this.normalizeStoreItem(item)))
this.showChainPicker = false
this.showMerchantPicker = false
this.activePickerIndex = -1
@@ -762,7 +779,7 @@ export default {
const summary = this.parseStoredJson(record.summary, record.summary || '')
this.form.summary = typeof summary === 'string' ? summary : ''
const storeList = this.parseStoredJson(record.storeList, [])
- this.storeList = (Array.isArray(storeList) ? storeList : []).map(item => this.normalizeStoreItem(item))
+ this.storeList = this.ensureStoreKeys((Array.isArray(storeList) ? storeList : []).map(item => this.normalizeStoreItem(item)))
} catch (error) {
await this.toast(error && error.message ? error.message : '填报记录加载失败')
} finally {