perf(门店选择): 门店明细移出页面 data,修复首屏卡顿
门店接口 /shop/merchant/groupByChain 一次返回 8105 家门店(约 1.1MB)。
此前把门店明细原样放进页面 data,data 树膨胀到 1118KB,导致此后每次
setData 都要重新 diff/序列化整棵树——即使载荷只有 1 个字段,耗时也从
约 490ms 涨到约 1000ms,首屏因此多花约 3.5s。
改为把明细挂在实例属性 merchantStore 上(不进页面 data),
merchantChainList 只保留 {id, text, merchantCount} 骨架,
新增 getMerchantsByChainId() / getVisibleMerchants() 按需取数。
涉及页面:
- packageUser/self-report/create.vue
- packageUser/chronic/index.vue
- pages/task/detail.vue
- pages/share/create.vue
- pages/share/index.vue
- pages/audit/components/AuditShareItem.vue
实测(微信开发者工具自动化):
- 页面 data 门店明细 1118KB -> 1KB
- 单字段 setData 998ms -> 10~53ms
- self-report/create 首屏 9055ms -> 5341ms
- 门店 picker 选项数不变(大参林 2700 项),搜索与选中回填均正常
This commit is contained in:
@@ -446,8 +446,10 @@ export default {
|
|||||||
return list.length ? list.map(item => ({id: item.id, text: item.text})) : [{id: '', text: '暂无连锁'}]
|
return list.length ? list.map(item => ({id: item.id, text: item.text})) : [{id: '', text: '暂无连锁'}]
|
||||||
},
|
},
|
||||||
merchantOptions() {
|
merchantOptions() {
|
||||||
const chain = this.merchantChainList.find(item => String(item.id) === String(this.form.chainId))
|
// 门店明细挂在实例的 merchantStore 上,不进页面 data(见 setMerchantChains)
|
||||||
const merchants = chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
const chainList = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
||||||
|
const hasChain = chainList.some(item => String(item.id) === String(this.form.chainId))
|
||||||
|
const merchants = hasChain ? this.getMerchantsByChainId(this.form.chainId) : []
|
||||||
return merchants.length ? merchants : [{id: '', text: '无门店'}]
|
return merchants.length ? merchants : [{id: '', text: '无门店'}]
|
||||||
},
|
},
|
||||||
merchantFilteredOptions() {
|
merchantFilteredOptions() {
|
||||||
@@ -494,6 +496,10 @@ export default {
|
|||||||
this.merchantPickerValue = [0]
|
this.merchantPickerValue = [0]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
// 门店明细挂实例上而非 data:data 里的一切都会进页面 data 树并被 setData 序列化
|
||||||
|
this.merchantStore = []
|
||||||
|
},
|
||||||
onShow() {
|
onShow() {
|
||||||
this.fetchMerchantList()
|
this.fetchMerchantList()
|
||||||
},
|
},
|
||||||
@@ -503,11 +509,12 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const {data} = await merchantGroupByChainReq({})
|
const {data} = await merchantGroupByChainReq({})
|
||||||
const list = this.unwrapList(data)
|
const list = this.unwrapList(data)
|
||||||
this.merchantChainList = list
|
const chains = list
|
||||||
.map((item, index) => this.normalizeMerchantChain(item, index))
|
.map((item, index) => this.normalizeMerchantChain(item, index))
|
||||||
.filter(item => Array.isArray(item.merchants) && item.merchants.length > 0)
|
.filter(item => Array.isArray(item.merchants) && item.merchants.length > 0)
|
||||||
|
this.setMerchantChains(chains)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.merchantChainList = []
|
this.setMerchantChains([])
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '门店列表获取失败',
|
title: '门店列表获取失败',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
@@ -516,6 +523,27 @@ export default {
|
|||||||
this.merchantLoading = false
|
this.merchantLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 门店明细(全量可达 8000+ 条)只放在实例上,不进页面 data。
|
||||||
|
// 一旦放进 data,页面 data 树会膨胀到 1MB+,此后每次 setData 都要重新
|
||||||
|
// diff/序列化整棵树,连只含一个字段的 setData 也会从 ~490ms 涨到 ~1000ms。
|
||||||
|
setMerchantChains(chains) {
|
||||||
|
const list = Array.isArray(chains) ? chains : []
|
||||||
|
this.merchantStore = list.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchants: Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
}))
|
||||||
|
this.merchantChainList = this.merchantStore.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchantCount: chain.merchants.length
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
getMerchantsByChainId(chainId) {
|
||||||
|
const store = Array.isArray(this.merchantStore) ? this.merchantStore : []
|
||||||
|
const chain = store.find(item => String(item.id) === String(chainId))
|
||||||
|
return chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
},
|
||||||
openChainPicker() {
|
openChainPicker() {
|
||||||
this.showChainPicker = true
|
this.showChainPicker = true
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -385,11 +385,14 @@ export default {
|
|||||||
},
|
},
|
||||||
merchantChainOptions() {
|
merchantChainOptions() {
|
||||||
const list = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
const list = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
||||||
return list.length ? list : [{id: '', text: '暂无连锁', merchants: []}]
|
return list.length ? list : [{id: '', text: '暂无连锁', merchantCount: 0}]
|
||||||
},
|
},
|
||||||
merchantStoreOptions() {
|
merchantStoreOptions() {
|
||||||
const currentChain = this.merchantChainOptions.find(chain => String(chain.id) === String(this.form.chainId)) || {}
|
// 门店明细不放在页面 data 里(见 setMerchantChains),从实例上的 store 取。
|
||||||
const merchants = Array.isArray(currentChain.merchants) ? currentChain.merchants : []
|
// 这里读 merchantChainList 是为了建立响应式依赖:门店数据到达后需要重算。
|
||||||
|
const chainList = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
||||||
|
const hasChain = chainList.some(chain => String(chain.id) === String(this.form.chainId))
|
||||||
|
const merchants = hasChain ? this.getMerchantsByChainId(this.form.chainId) : []
|
||||||
const keyword = (this.merchantStoreSearchKeyword || '').trim()
|
const keyword = (this.merchantStoreSearchKeyword || '').trim()
|
||||||
const filteredMerchants = this.filterMerchantStores(merchants)
|
const filteredMerchants = this.filterMerchantStores(merchants)
|
||||||
return filteredMerchants.length ? filteredMerchants : [{id: '', text: keyword ? '无匹配门店' : '无门店'}]
|
return filteredMerchants.length ? filteredMerchants : [{id: '', text: keyword ? '无匹配门店' : '无门店'}]
|
||||||
@@ -442,6 +445,10 @@ export default {
|
|||||||
this.merchantPickerValue = [0]
|
this.merchantPickerValue = [0]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
// 门店明细挂实例上而非 data:data 里的一切都会进页面 data 树并被 setData 序列化。
|
||||||
|
this.merchantStore = []
|
||||||
|
},
|
||||||
async onShow() {
|
async onShow() {
|
||||||
this.isLoggedIn = !!getUserInfo().token
|
this.isLoggedIn = !!getUserInfo().token
|
||||||
if (!this.hasInitialized) {
|
if (!this.hasInitialized) {
|
||||||
@@ -803,12 +810,13 @@ export default {
|
|||||||
const {data} = await merchantGroupByChainReq({})
|
const {data} = await merchantGroupByChainReq({})
|
||||||
const list = this.unwrapList(data)
|
const list = this.unwrapList(data)
|
||||||
const groupedList = this.groupMerchantListByChain(list)
|
const groupedList = this.groupMerchantListByChain(list)
|
||||||
this.merchantChainList = (groupedList.length
|
const chains = (groupedList.length
|
||||||
? groupedList
|
? groupedList
|
||||||
: list.map((item, index) => this.normalizeMerchantChain(item, index)))
|
: list.map((item, index) => this.normalizeMerchantChain(item, index)))
|
||||||
.filter(item => Array.isArray(item.merchants) && item.merchants.length > 0)
|
.filter(item => Array.isArray(item.merchants) && item.merchants.length > 0)
|
||||||
|
this.setMerchantChains(chains)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.merchantChainList = []
|
this.setMerchantChains([])
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '门店列表获取失败',
|
title: '门店列表获取失败',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
@@ -817,6 +825,27 @@ export default {
|
|||||||
this.merchantLoading = false
|
this.merchantLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 门店明细(全量可达 8000+ 条)只放在实例上,不进页面 data。
|
||||||
|
// 一旦放进 data,页面 data 树会膨胀到 1MB+,此后每次 setData 都要重新
|
||||||
|
// diff/序列化整棵树,连只含一个字段的 setData 也会从 ~490ms 涨到 ~1000ms。
|
||||||
|
setMerchantChains(chains) {
|
||||||
|
const list = Array.isArray(chains) ? chains : []
|
||||||
|
this.merchantStore = list.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchants: Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
}))
|
||||||
|
this.merchantChainList = this.merchantStore.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchantCount: chain.merchants.length
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
getMerchantsByChainId(chainId) {
|
||||||
|
const store = Array.isArray(this.merchantStore) ? this.merchantStore : []
|
||||||
|
const chain = store.find(item => String(item.id) === String(chainId))
|
||||||
|
return chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
},
|
||||||
openChainPicker() {
|
openChainPicker() {
|
||||||
if (!this.merchantChainList.length) return
|
if (!this.merchantChainList.length) return
|
||||||
const chainIndex = this.merchantChainOptions.findIndex(item => String(item.id) === String(this.form.chainId))
|
const chainIndex = this.merchantChainOptions.findIndex(item => String(item.id) === String(this.form.chainId))
|
||||||
|
|||||||
@@ -370,26 +370,20 @@ export default {
|
|||||||
editMerchantChainOptions() {
|
editMerchantChainOptions() {
|
||||||
const list = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
const list = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
||||||
const keyword = (this.editMerchantSearchKeyword || '').trim()
|
const keyword = (this.editMerchantSearchKeyword || '').trim()
|
||||||
if (!keyword) return list.length ? list : [{id: '', text: '暂无连锁', merchants: []}]
|
if (!keyword) return list.length ? list : [{id: '', text: '暂无连锁', merchantCount: 0}]
|
||||||
const filtered = list
|
const filtered = list
|
||||||
.map(chain => {
|
.map(chain => {
|
||||||
const merchants = Array.isArray(chain.merchants) ? chain.merchants : []
|
const visible = this.getVisibleMerchants(chain)
|
||||||
const chainMatch = (chain.text || '').includes(keyword)
|
if (!visible.length) return null
|
||||||
if (chainMatch) return {...chain}
|
return Object.assign({}, chain, {merchantCount: visible.length})
|
||||||
const matchedMerchants = merchants.filter(merchant => (merchant.text || '').includes(keyword))
|
|
||||||
if (!matchedMerchants.length) return null
|
|
||||||
return {
|
|
||||||
...chain,
|
|
||||||
merchants: matchedMerchants
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
return filtered.length ? filtered : [{id: '', text: '无匹配连锁', merchants: []}]
|
return filtered.length ? filtered : [{id: '', text: '无匹配连锁', merchantCount: 0}]
|
||||||
},
|
},
|
||||||
editMerchantStoreOptions() {
|
editMerchantStoreOptions() {
|
||||||
const chainIndex = Number(this.editMerchantPickerValue[0] || 0)
|
const chainIndex = Number(this.editMerchantPickerValue[0] || 0)
|
||||||
const currentChain = this.editMerchantChainOptions[chainIndex] || this.editMerchantChainOptions[0] || {}
|
const currentChain = this.editMerchantChainOptions[chainIndex] || this.editMerchantChainOptions[0] || {}
|
||||||
const merchants = Array.isArray(currentChain.merchants) ? currentChain.merchants : []
|
const merchants = this.getVisibleMerchants(currentChain)
|
||||||
return merchants.length ? merchants : [{id: '', text: '无门店'}]
|
return merchants.length ? merchants : [{id: '', text: '无门店'}]
|
||||||
},
|
},
|
||||||
editMerchantPickerIndexes() {
|
editMerchantPickerIndexes() {
|
||||||
@@ -398,12 +392,12 @@ export default {
|
|||||||
let chainIndex = chainList.findIndex(item => item.id === this.editForm.chainId)
|
let chainIndex = chainList.findIndex(item => item.id === this.editForm.chainId)
|
||||||
if (chainIndex < 0 && this.editForm.merchantId) {
|
if (chainIndex < 0 && this.editForm.merchantId) {
|
||||||
chainIndex = chainList.findIndex(item => {
|
chainIndex = chainList.findIndex(item => {
|
||||||
const merchants = Array.isArray(item.merchants) ? item.merchants : []
|
const merchants = this.getMerchantsByChainId(item && item.id)
|
||||||
return merchants.some(merchant => merchant.id === this.editForm.merchantId)
|
return merchants.some(merchant => merchant.id === this.editForm.merchantId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (chainIndex < 0) chainIndex = 0
|
if (chainIndex < 0) chainIndex = 0
|
||||||
const merchants = Array.isArray(chainList[chainIndex].merchants) ? chainList[chainIndex].merchants : []
|
const merchants = this.getMerchantsByChainId(chainList[chainIndex] && chainList[chainIndex].id)
|
||||||
let merchantIndex = merchants.findIndex(item => item.id === this.editForm.merchantId)
|
let merchantIndex = merchants.findIndex(item => item.id === this.editForm.merchantId)
|
||||||
if (merchantIndex < 0) merchantIndex = 0
|
if (merchantIndex < 0) merchantIndex = 0
|
||||||
return [chainIndex, merchantIndex]
|
return [chainIndex, merchantIndex]
|
||||||
@@ -470,10 +464,28 @@ export default {
|
|||||||
this.editMerchantPickerValue = [0, 0]
|
this.editMerchantPickerValue = [0, 0]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
// 门店明细挂实例上而非 data:data 里的一切都会进页面 data 树并被 setData 序列化
|
||||||
|
this.merchantStore = []
|
||||||
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.clearGoodsCodeTimers()
|
this.clearGoodsCodeTimers()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 门店明细只存在实例的 merchantStore 上(不进页面 data),按连锁 id 取
|
||||||
|
getMerchantsByChainId(chainId) {
|
||||||
|
const store = Array.isArray(this.merchantStore) ? this.merchantStore : []
|
||||||
|
const chain = store.find(item => String(item.id) === String(chainId))
|
||||||
|
return chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
},
|
||||||
|
// 搜索关键词命中的门店:连锁名命中则整列保留,否则按门店名过滤
|
||||||
|
getVisibleMerchants(chain) {
|
||||||
|
const merchants = this.getMerchantsByChainId(chain && chain.id)
|
||||||
|
const keyword = (this.editMerchantSearchKeyword || '').trim()
|
||||||
|
if (!keyword) return merchants
|
||||||
|
if ((chain.text || '').includes(keyword)) return merchants
|
||||||
|
return merchants.filter(merchant => (merchant.text || '').includes(keyword))
|
||||||
|
},
|
||||||
async toggleDetailExpanded() {
|
async toggleDetailExpanded() {
|
||||||
const nextExpanded = !this.detailExpanded
|
const nextExpanded = !this.detailExpanded
|
||||||
this.detailExpanded = nextExpanded
|
this.detailExpanded = nextExpanded
|
||||||
@@ -1048,11 +1060,12 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const {data} = await merchantGroupByChainReq({})
|
const {data} = await merchantGroupByChainReq({})
|
||||||
const list = this.unwrapNestedList(data)
|
const list = this.unwrapNestedList(data)
|
||||||
this.merchantChainList = list
|
const chains = list
|
||||||
.map((item, index) => this.normalizeMerchantChain(item, index))
|
.map((item, index) => this.normalizeMerchantChain(item, index))
|
||||||
.filter(item => Array.isArray(item.merchants) && item.merchants.length > 0)
|
.filter(item => Array.isArray(item.merchants) && item.merchants.length > 0)
|
||||||
|
this.setMerchantChains(chains)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.merchantChainList = []
|
this.setMerchantChains([])
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '门店列表获取失败',
|
title: '门店列表获取失败',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
@@ -1061,6 +1074,22 @@ export default {
|
|||||||
this.merchantLoading = false
|
this.merchantLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 门店明细(全量可达 8000+ 条)只放在实例上,不进页面 data。
|
||||||
|
// 一旦放进 data,页面 data 树会膨胀到 1MB+,此后每次 setData 都要重新
|
||||||
|
// diff/序列化整棵树,连只含一个字段的 setData 也会从 ~490ms 涨到 ~1000ms。
|
||||||
|
setMerchantChains(chains) {
|
||||||
|
const list = Array.isArray(chains) ? chains : []
|
||||||
|
this.merchantStore = list.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchants: Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
}))
|
||||||
|
this.merchantChainList = this.merchantStore.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchantCount: chain.merchants.length
|
||||||
|
}))
|
||||||
|
},
|
||||||
async openEditMerchantPicker() {
|
async openEditMerchantPicker() {
|
||||||
if (!this.merchantChainList || this.merchantChainList.length === 0) {
|
if (!this.merchantChainList || this.merchantChainList.length === 0) {
|
||||||
await this.getMerchantList()
|
await this.getMerchantList()
|
||||||
@@ -1075,7 +1104,7 @@ export default {
|
|||||||
const chainIndex = Number(this.editMerchantPickerValue[0] || 0)
|
const chainIndex = Number(this.editMerchantPickerValue[0] || 0)
|
||||||
const merchantIndex = Number(this.editMerchantPickerValue[1] || 0)
|
const merchantIndex = Number(this.editMerchantPickerValue[1] || 0)
|
||||||
const chain = this.editMerchantChainOptions[chainIndex] || null
|
const chain = this.editMerchantChainOptions[chainIndex] || null
|
||||||
const merchants = chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
const merchants = this.getVisibleMerchants(chain)
|
||||||
const selected = merchants[merchantIndex]
|
const selected = merchants[merchantIndex]
|
||||||
if (!selected || selected.id === '' || selected.id === null || selected.id === undefined) {
|
if (!selected || selected.id === '' || selected.id === null || selected.id === undefined) {
|
||||||
return
|
return
|
||||||
@@ -1096,7 +1125,7 @@ export default {
|
|||||||
if (!Number.isFinite(chainIndex) || chainIndex < 0) chainIndex = 0
|
if (!Number.isFinite(chainIndex) || chainIndex < 0) chainIndex = 0
|
||||||
if (!Number.isFinite(merchantIndex) || merchantIndex < 0) merchantIndex = 0
|
if (!Number.isFinite(merchantIndex) || merchantIndex < 0) merchantIndex = 0
|
||||||
const chain = this.editMerchantChainOptions[chainIndex] || this.editMerchantChainOptions[0] || {}
|
const chain = this.editMerchantChainOptions[chainIndex] || this.editMerchantChainOptions[0] || {}
|
||||||
const merchants = Array.isArray(chain.merchants) ? chain.merchants : []
|
const merchants = this.getVisibleMerchants(chain)
|
||||||
if (!merchants.length) {
|
if (!merchants.length) {
|
||||||
merchantIndex = 0
|
merchantIndex = 0
|
||||||
} else if (chainIndex !== currentChainIndex || merchantIndex > merchants.length - 1) {
|
} else if (chainIndex !== currentChainIndex || merchantIndex > merchants.length - 1) {
|
||||||
|
|||||||
+50
-19
@@ -266,40 +266,35 @@ export default {
|
|||||||
merchantChainOptions() {
|
merchantChainOptions() {
|
||||||
const list = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
const list = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
||||||
const keyword = (this.merchantSearchKeyword || '').trim()
|
const keyword = (this.merchantSearchKeyword || '').trim()
|
||||||
if (!keyword) return list.length ? list : [{id: '', text: '暂无连锁', merchants: []}]
|
if (!keyword) return list.length ? list : [{id: '', text: '暂无连锁', merchantCount: 0}]
|
||||||
const filtered = list
|
const filtered = list
|
||||||
.map(chain => {
|
.map(chain => {
|
||||||
const merchants = Array.isArray(chain.merchants) ? chain.merchants : []
|
const visible = this.getVisibleMerchants(chain)
|
||||||
const chainMatch = (chain.text || '').includes(keyword)
|
if (!visible.length) return null
|
||||||
if (chainMatch) return {...chain}
|
return Object.assign({}, chain, {merchantCount: visible.length})
|
||||||
const matchedMerchants = merchants.filter(merchant => (merchant.text || '').includes(keyword))
|
|
||||||
if (!matchedMerchants.length) return null
|
|
||||||
return {
|
|
||||||
...chain,
|
|
||||||
merchants: matchedMerchants
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
return filtered.length ? filtered : [{id: '', text: '无匹配连锁', merchants: []}]
|
return filtered.length ? filtered : [{id: '', text: '无匹配连锁', merchantCount: 0}]
|
||||||
},
|
},
|
||||||
merchantStoreOptions() {
|
merchantStoreOptions() {
|
||||||
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
||||||
const currentChain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
const currentChain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
||||||
const merchants = Array.isArray(currentChain.merchants) ? currentChain.merchants : []
|
const merchants = this.getVisibleMerchants(currentChain)
|
||||||
return merchants.length ? merchants : [{id: '', text: '无门店'}]
|
return merchants.length ? merchants : [{id: '', text: '无门店'}]
|
||||||
},
|
},
|
||||||
|
// 门店明细只存在实例的 merchantStore 上(不进页面 data),按连锁 id 取
|
||||||
merchantPickerIndexes() {
|
merchantPickerIndexes() {
|
||||||
const chainList = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
const chainList = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
||||||
if (!chainList.length) return [0, 0]
|
if (!chainList.length) return [0, 0]
|
||||||
let chainIndex = chainList.findIndex(item => item.id === this.form.chainId)
|
let chainIndex = chainList.findIndex(item => item.id === this.form.chainId)
|
||||||
if (chainIndex < 0 && this.form.merchantId) {
|
if (chainIndex < 0 && this.form.merchantId) {
|
||||||
chainIndex = chainList.findIndex(item => {
|
chainIndex = chainList.findIndex(item => {
|
||||||
const merchants = Array.isArray(item.merchants) ? item.merchants : []
|
const merchants = this.getMerchantsByChainId(item.id)
|
||||||
return merchants.some(merchant => merchant.id === this.form.merchantId)
|
return merchants.some(merchant => merchant.id === this.form.merchantId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (chainIndex < 0) chainIndex = 0
|
if (chainIndex < 0) chainIndex = 0
|
||||||
const merchants = Array.isArray(chainList[chainIndex].merchants) ? chainList[chainIndex].merchants : []
|
const merchants = this.getMerchantsByChainId(chainList[chainIndex].id)
|
||||||
let merchantIndex = merchants.findIndex(item => item.id === this.form.merchantId)
|
let merchantIndex = merchants.findIndex(item => item.id === this.form.merchantId)
|
||||||
if (merchantIndex < 0) merchantIndex = 0
|
if (merchantIndex < 0) merchantIndex = 0
|
||||||
return [chainIndex, merchantIndex]
|
return [chainIndex, merchantIndex]
|
||||||
@@ -365,6 +360,10 @@ export default {
|
|||||||
this.merchantPickerValue = [0, 0]
|
this.merchantPickerValue = [0, 0]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
// 门店明细挂实例上而非 data:data 里的一切都会进页面 data 树并被 setData 序列化
|
||||||
|
this.merchantStore = []
|
||||||
|
},
|
||||||
onLoad(options = {}) {
|
onLoad(options = {}) {
|
||||||
this.lat = this.parseNumber(options.lat)
|
this.lat = this.parseNumber(options.lat)
|
||||||
this.lng = this.parseNumber(options.lng)
|
this.lng = this.parseNumber(options.lng)
|
||||||
@@ -373,6 +372,20 @@ export default {
|
|||||||
this.init()
|
this.init()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 门店明细只存在实例的 merchantStore 上(不进页面 data),按连锁 id 取
|
||||||
|
getMerchantsByChainId(chainId) {
|
||||||
|
const store = Array.isArray(this.merchantStore) ? this.merchantStore : []
|
||||||
|
const chain = store.find(item => String(item.id) === String(chainId))
|
||||||
|
return chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
},
|
||||||
|
// 搜索关键词命中的门店:连锁名命中则整列保留,否则按门店名过滤
|
||||||
|
getVisibleMerchants(chain) {
|
||||||
|
const merchants = this.getMerchantsByChainId(chain && chain.id)
|
||||||
|
const keyword = (this.merchantSearchKeyword || '').trim()
|
||||||
|
if (!keyword) return merchants
|
||||||
|
if ((chain.text || '').includes(keyword)) return merchants
|
||||||
|
return merchants.filter(merchant => (merchant.text || '').includes(keyword))
|
||||||
|
},
|
||||||
parseNumber(value) {
|
parseNumber(value) {
|
||||||
if (value === '' || value === null || value === undefined) return null
|
if (value === '' || value === null || value === undefined) return null
|
||||||
const n = Number(value)
|
const n = Number(value)
|
||||||
@@ -448,8 +461,9 @@ export default {
|
|||||||
},
|
},
|
||||||
flattenMerchantsFromChains(chainList) {
|
flattenMerchantsFromChains(chainList) {
|
||||||
const rows = []
|
const rows = []
|
||||||
|
// chainList 可能只是骨架(无 merchants),明细统一从实例的 merchantStore 取
|
||||||
;(Array.isArray(chainList) ? chainList : []).forEach(chain => {
|
;(Array.isArray(chainList) ? chainList : []).forEach(chain => {
|
||||||
const merchants = Array.isArray(chain.merchants) ? chain.merchants : []
|
const merchants = this.getMerchantsByChainId(chain && chain.id)
|
||||||
merchants.forEach(merchant => {
|
merchants.forEach(merchant => {
|
||||||
rows.push({
|
rows.push({
|
||||||
...merchant,
|
...merchant,
|
||||||
@@ -897,11 +911,12 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const {data} = await merchantGroupByChainReq({})
|
const {data} = await merchantGroupByChainReq({})
|
||||||
const list = this.unwrapList(data)
|
const list = this.unwrapList(data)
|
||||||
this.merchantChainList = list
|
const chains = list
|
||||||
.map((item, index) => this.normalizeMerchantChain(item, index))
|
.map((item, index) => this.normalizeMerchantChain(item, index))
|
||||||
.filter(item => Array.isArray(item.merchants) && item.merchants.length > 0)
|
.filter(item => Array.isArray(item.merchants) && item.merchants.length > 0)
|
||||||
|
this.setMerchantChains(chains)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.merchantChainList = []
|
this.setMerchantChains([])
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '门店列表获取失败',
|
title: '门店列表获取失败',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
@@ -910,6 +925,22 @@ export default {
|
|||||||
this.merchantLoading = false
|
this.merchantLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 门店明细(全量可达 8000+ 条)只放在实例上,不进页面 data。
|
||||||
|
// 一旦放进 data,页面 data 树会膨胀到 1MB+,此后每次 setData 都要重新
|
||||||
|
// diff/序列化整棵树,连只含一个字段的 setData 也会从 ~490ms 涨到 ~1000ms。
|
||||||
|
setMerchantChains(chains) {
|
||||||
|
const list = Array.isArray(chains) ? chains : []
|
||||||
|
this.merchantStore = list.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchants: Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
}))
|
||||||
|
this.merchantChainList = this.merchantStore.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchantCount: chain.merchants.length
|
||||||
|
}))
|
||||||
|
},
|
||||||
async getProductsByMerchant() {
|
async getProductsByMerchant() {
|
||||||
if (!this.form.merchantId) {
|
if (!this.form.merchantId) {
|
||||||
this.form.list = []
|
this.form.list = []
|
||||||
@@ -991,7 +1022,7 @@ export default {
|
|||||||
if (!Number.isFinite(chainIndex) || chainIndex < 0) chainIndex = 0
|
if (!Number.isFinite(chainIndex) || chainIndex < 0) chainIndex = 0
|
||||||
if (!Number.isFinite(merchantIndex) || merchantIndex < 0) merchantIndex = 0
|
if (!Number.isFinite(merchantIndex) || merchantIndex < 0) merchantIndex = 0
|
||||||
const chain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
const chain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
||||||
const merchants = Array.isArray(chain.merchants) ? chain.merchants : []
|
const merchants = this.getVisibleMerchants(chain)
|
||||||
if (!merchants.length) {
|
if (!merchants.length) {
|
||||||
merchantIndex = 0
|
merchantIndex = 0
|
||||||
} else if (chainIndex !== currentChainIndex || merchantIndex > merchants.length - 1) {
|
} else if (chainIndex !== currentChainIndex || merchantIndex > merchants.length - 1) {
|
||||||
@@ -1003,7 +1034,7 @@ export default {
|
|||||||
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
||||||
const merchantIndex = Number(this.merchantPickerValue[1] || 0)
|
const merchantIndex = Number(this.merchantPickerValue[1] || 0)
|
||||||
const chain = this.merchantChainOptions[chainIndex] || null
|
const chain = this.merchantChainOptions[chainIndex] || null
|
||||||
const merchants = chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
const merchants = this.getVisibleMerchants(chain)
|
||||||
const selected = merchants[merchantIndex]
|
const selected = merchants[merchantIndex]
|
||||||
if (!selected || selected.id === '' || selected.id === null || selected.id === undefined) {
|
if (!selected || selected.id === '' || selected.id === null || selected.id === undefined) {
|
||||||
return
|
return
|
||||||
|
|||||||
+46
-18
@@ -380,26 +380,20 @@ export default {
|
|||||||
merchantChainOptions() {
|
merchantChainOptions() {
|
||||||
const list = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
const list = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
||||||
const keyword = (this.merchantSearchKeyword || '').trim()
|
const keyword = (this.merchantSearchKeyword || '').trim()
|
||||||
if (!keyword) return list.length ? list : [{id: '', text: '暂无连锁', merchants: []}]
|
if (!keyword) return list.length ? list : [{id: '', text: '暂无连锁', merchantCount: 0}]
|
||||||
const filtered = list
|
const filtered = list
|
||||||
.map(chain => {
|
.map(chain => {
|
||||||
const merchants = Array.isArray(chain.merchants) ? chain.merchants : []
|
const visible = this.getVisibleMerchants(chain)
|
||||||
const chainMatch = (chain.text || '').includes(keyword)
|
if (!visible.length) return null
|
||||||
if (chainMatch) return {...chain}
|
return Object.assign({}, chain, {merchantCount: visible.length})
|
||||||
const matchedMerchants = merchants.filter(merchant => (merchant.text || '').includes(keyword))
|
|
||||||
if (!matchedMerchants.length) return null
|
|
||||||
return {
|
|
||||||
...chain,
|
|
||||||
merchants: matchedMerchants
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
return filtered.length ? filtered : [{id: '', text: '无匹配连锁', merchants: []}]
|
return filtered.length ? filtered : [{id: '', text: '无匹配连锁', merchantCount: 0}]
|
||||||
},
|
},
|
||||||
merchantStoreOptions() {
|
merchantStoreOptions() {
|
||||||
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
||||||
const currentChain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
const currentChain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
||||||
const merchants = Array.isArray(currentChain.merchants) ? currentChain.merchants : []
|
const merchants = this.getVisibleMerchants(currentChain)
|
||||||
return merchants.length ? merchants : [{id: '', text: '无门店'}]
|
return merchants.length ? merchants : [{id: '', text: '无门店'}]
|
||||||
},
|
},
|
||||||
merchantPickerIndexes() {
|
merchantPickerIndexes() {
|
||||||
@@ -408,12 +402,12 @@ export default {
|
|||||||
let chainIndex = chainList.findIndex(item => item.id === this.merchantChainId)
|
let chainIndex = chainList.findIndex(item => item.id === this.merchantChainId)
|
||||||
if (chainIndex < 0 && this.merchantId) {
|
if (chainIndex < 0 && this.merchantId) {
|
||||||
chainIndex = chainList.findIndex(item => {
|
chainIndex = chainList.findIndex(item => {
|
||||||
const merchants = Array.isArray(item.merchants) ? item.merchants : []
|
const merchants = this.getMerchantsByChainId(item.id)
|
||||||
return merchants.some(merchant => merchant.id === this.merchantId)
|
return merchants.some(merchant => merchant.id === this.merchantId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (chainIndex < 0) chainIndex = 0
|
if (chainIndex < 0) chainIndex = 0
|
||||||
const merchants = Array.isArray(chainList[chainIndex].merchants) ? chainList[chainIndex].merchants : []
|
const merchants = this.getMerchantsByChainId(chainList[chainIndex].id)
|
||||||
let merchantIndex = merchants.findIndex(item => item.id === this.merchantId)
|
let merchantIndex = merchants.findIndex(item => item.id === this.merchantId)
|
||||||
if (merchantIndex < 0) merchantIndex = 0
|
if (merchantIndex < 0) merchantIndex = 0
|
||||||
return [chainIndex, merchantIndex]
|
return [chainIndex, merchantIndex]
|
||||||
@@ -446,6 +440,10 @@ export default {
|
|||||||
this.merchantPickerValue = [0, 0]
|
this.merchantPickerValue = [0, 0]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
// 门店明细挂实例上而非 data:data 里的一切都会进页面 data 树并被 setData 序列化
|
||||||
|
this.merchantStore = []
|
||||||
|
},
|
||||||
async onShow() {
|
async onShow() {
|
||||||
await this.refreshPageData()
|
await this.refreshPageData()
|
||||||
},
|
},
|
||||||
@@ -458,6 +456,20 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
dayjs,
|
dayjs,
|
||||||
|
// 门店明细只存在实例的 merchantStore 上(不进页面 data),按连锁 id 取
|
||||||
|
getMerchantsByChainId(chainId) {
|
||||||
|
const store = Array.isArray(this.merchantStore) ? this.merchantStore : []
|
||||||
|
const chain = store.find(item => String(item.id) === String(chainId))
|
||||||
|
return chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
},
|
||||||
|
// 搜索关键词命中的门店:连锁名命中则整列保留,否则按门店名过滤
|
||||||
|
getVisibleMerchants(chain) {
|
||||||
|
const merchants = this.getMerchantsByChainId(chain && chain.id)
|
||||||
|
const keyword = (this.merchantSearchKeyword || '').trim()
|
||||||
|
if (!keyword) return merchants
|
||||||
|
if ((chain.text || '').includes(keyword)) return merchants
|
||||||
|
return merchants.filter(merchant => (merchant.text || '').includes(keyword))
|
||||||
|
},
|
||||||
async refreshPageData() {
|
async refreshPageData() {
|
||||||
if (getUserInfo().token) {
|
if (getUserInfo().token) {
|
||||||
await this.getUserData()
|
await this.getUserData()
|
||||||
@@ -561,11 +573,11 @@ export default {
|
|||||||
const chainList = list
|
const chainList = list
|
||||||
.map((item, index) => this.normalizeMerchantChain(item, index))
|
.map((item, index) => this.normalizeMerchantChain(item, index))
|
||||||
.filter(item => Array.isArray(item.merchants) && item.merchants.length)
|
.filter(item => Array.isArray(item.merchants) && item.merchants.length)
|
||||||
this.merchantChainList = [{
|
this.setMerchantChains([{
|
||||||
id: '',
|
id: '',
|
||||||
text: '全部连锁',
|
text: '全部连锁',
|
||||||
merchants: [{id: '', text: '全部门店'}]
|
merchants: [{id: '', text: '全部门店'}]
|
||||||
}].concat(chainList)
|
}].concat(chainList))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '门店列表获取失败',
|
title: '门店列表获取失败',
|
||||||
@@ -575,6 +587,22 @@ export default {
|
|||||||
this.merchantLoading = false
|
this.merchantLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 门店明细(全量可达 8000+ 条)只放在实例上,不进页面 data。
|
||||||
|
// 一旦放进 data,页面 data 树会膨胀到 1MB+,此后每次 setData 都要重新
|
||||||
|
// diff/序列化整棵树,连只含一个字段的 setData 也会从 ~490ms 涨到 ~1000ms。
|
||||||
|
setMerchantChains(chains) {
|
||||||
|
const list = Array.isArray(chains) ? chains : []
|
||||||
|
this.merchantStore = list.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchants: Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
}))
|
||||||
|
this.merchantChainList = this.merchantStore.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchantCount: chain.merchants.length
|
||||||
|
}))
|
||||||
|
},
|
||||||
async openMerchantPicker() {
|
async openMerchantPicker() {
|
||||||
if (!this.merchantChainList || this.merchantChainList.length <= 1) {
|
if (!this.merchantChainList || this.merchantChainList.length <= 1) {
|
||||||
await this.getMerchantList()
|
await this.getMerchantList()
|
||||||
@@ -594,7 +622,7 @@ export default {
|
|||||||
if (!Number.isFinite(chainIndex) || chainIndex < 0) chainIndex = 0
|
if (!Number.isFinite(chainIndex) || chainIndex < 0) chainIndex = 0
|
||||||
if (!Number.isFinite(merchantIndex) || merchantIndex < 0) merchantIndex = 0
|
if (!Number.isFinite(merchantIndex) || merchantIndex < 0) merchantIndex = 0
|
||||||
const chain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
const chain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
||||||
const merchants = Array.isArray(chain.merchants) ? chain.merchants : []
|
const merchants = this.getVisibleMerchants(chain)
|
||||||
if (!merchants.length) {
|
if (!merchants.length) {
|
||||||
merchantIndex = 0
|
merchantIndex = 0
|
||||||
} else if (chainIndex !== currentChainIndex || merchantIndex > merchants.length - 1) {
|
} else if (chainIndex !== currentChainIndex || merchantIndex > merchants.length - 1) {
|
||||||
@@ -606,7 +634,7 @@ export default {
|
|||||||
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
||||||
const merchantIndex = Number(this.merchantPickerValue[1] || 0)
|
const merchantIndex = Number(this.merchantPickerValue[1] || 0)
|
||||||
const chain = this.merchantChainOptions[chainIndex] || null
|
const chain = this.merchantChainOptions[chainIndex] || null
|
||||||
const merchants = chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
const merchants = this.getVisibleMerchants(chain)
|
||||||
const selected = merchants[merchantIndex] || null
|
const selected = merchants[merchantIndex] || null
|
||||||
if (!selected) return
|
if (!selected) return
|
||||||
this.merchantChainId = chain ? (chain.id ?? '') : ''
|
this.merchantChainId = chain ? (chain.id ?? '') : ''
|
||||||
|
|||||||
+49
-19
@@ -644,26 +644,20 @@ export default {
|
|||||||
merchantChainOptions() {
|
merchantChainOptions() {
|
||||||
const list = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
const list = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
||||||
const keyword = (this.merchantSearchKeyword || '').trim()
|
const keyword = (this.merchantSearchKeyword || '').trim()
|
||||||
if (!keyword) return list.length ? list : [{id: '', text: '暂无连锁', merchants: []}]
|
if (!keyword) return list.length ? list : [{id: '', text: '暂无连锁', merchantCount: 0}]
|
||||||
const filtered = list
|
const filtered = list
|
||||||
.map(chain => {
|
.map(chain => {
|
||||||
const merchants = Array.isArray(chain.merchants) ? chain.merchants : []
|
const visible = this.getVisibleMerchants(chain)
|
||||||
const chainMatch = (chain.text || '').includes(keyword)
|
if (!visible.length) return null
|
||||||
if (chainMatch) return {...chain}
|
return Object.assign({}, chain, {merchantCount: visible.length})
|
||||||
const matchedMerchants = merchants.filter(merchant => (merchant.text || '').includes(keyword))
|
|
||||||
if (!matchedMerchants.length) return null
|
|
||||||
return {
|
|
||||||
...chain,
|
|
||||||
merchants: matchedMerchants
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
return filtered.length ? filtered : [{id: '', text: '无匹配连锁', merchants: []}]
|
return filtered.length ? filtered : [{id: '', text: '无匹配连锁', merchantCount: 0}]
|
||||||
},
|
},
|
||||||
merchantStoreOptions() {
|
merchantStoreOptions() {
|
||||||
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
||||||
const currentChain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
const currentChain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
||||||
const merchants = Array.isArray(currentChain.merchants) ? currentChain.merchants : []
|
const merchants = this.getVisibleMerchants(currentChain)
|
||||||
return merchants.length ? merchants : [{id: '', text: '无门店'}]
|
return merchants.length ? merchants : [{id: '', text: '无门店'}]
|
||||||
},
|
},
|
||||||
merchantIndicatorStyle() {
|
merchantIndicatorStyle() {
|
||||||
@@ -747,6 +741,10 @@ export default {
|
|||||||
this.merchantPickerValue = [0, 0]
|
this.merchantPickerValue = [0, 0]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
// 门店明细挂实例上而非 data:data 里的一切都会进页面 data 树并被 setData 序列化
|
||||||
|
this.merchantStore = []
|
||||||
|
},
|
||||||
async onLoad(options) {
|
async onLoad(options) {
|
||||||
this.auditEntry = String(options.fromAudit || '') === '1'
|
this.auditEntry = String(options.fromAudit || '') === '1'
|
||||||
this.auditId = options.auditId || ''
|
this.auditId = options.auditId || ''
|
||||||
@@ -781,6 +779,20 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 门店明细只存在实例的 merchantStore 上(不进页面 data),按连锁 id 取
|
||||||
|
getMerchantsByChainId(chainId) {
|
||||||
|
const store = Array.isArray(this.merchantStore) ? this.merchantStore : []
|
||||||
|
const chain = store.find(item => String(item.id) === String(chainId))
|
||||||
|
return chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
},
|
||||||
|
// 搜索关键词命中的门店:连锁名命中则整列保留,否则按门店名过滤
|
||||||
|
getVisibleMerchants(chain) {
|
||||||
|
const merchants = this.getMerchantsByChainId(chain && chain.id)
|
||||||
|
const keyword = (this.merchantSearchKeyword || '').trim()
|
||||||
|
if (!keyword) return merchants
|
||||||
|
if ((chain.text || '').includes(keyword)) return merchants
|
||||||
|
return merchants.filter(merchant => (merchant.text || '').includes(keyword))
|
||||||
|
},
|
||||||
calReward() {
|
calReward() {
|
||||||
const reward = this.resolveTaskAmount([
|
const reward = this.resolveTaskAmount([
|
||||||
this.task && this.task.reward,
|
this.task && this.task.reward,
|
||||||
@@ -978,8 +990,9 @@ export default {
|
|||||||
},
|
},
|
||||||
flattenMerchantsFromChains(chainList) {
|
flattenMerchantsFromChains(chainList) {
|
||||||
const list = []
|
const list = []
|
||||||
|
// chainList 可能只是骨架(无 merchants),明细统一从实例的 merchantStore 取
|
||||||
;(Array.isArray(chainList) ? chainList : []).forEach(chain => {
|
;(Array.isArray(chainList) ? chainList : []).forEach(chain => {
|
||||||
const merchants = Array.isArray(chain.merchants) ? chain.merchants : []
|
const merchants = this.getMerchantsByChainId(chain && chain.id)
|
||||||
merchants.forEach(merchant => {
|
merchants.forEach(merchant => {
|
||||||
if (!merchant || merchant.id === '' || merchant.id === null || merchant.id === undefined) return
|
if (!merchant || merchant.id === '' || merchant.id === null || merchant.id === undefined) return
|
||||||
list.push(Object.assign({}, merchant, {
|
list.push(Object.assign({}, merchant, {
|
||||||
@@ -1110,16 +1123,33 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const {data} = await merchantGroupByChainReq({})
|
const {data} = await merchantGroupByChainReq({})
|
||||||
const list = this.unwrapList(data)
|
const list = this.unwrapList(data)
|
||||||
this.merchantChainList = list
|
const chains = list
|
||||||
.map((item, index) => this.normalizeMerchantChain(item, index))
|
.map((item, index) => this.normalizeMerchantChain(item, index))
|
||||||
.filter(item => Array.isArray(item.merchants) && item.merchants.length)
|
.filter(item => Array.isArray(item.merchants) && item.merchants.length)
|
||||||
|
this.setMerchantChains(chains)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.merchantChainList = []
|
this.setMerchantChains([])
|
||||||
this.toast('门店列表获取失败')
|
this.toast('门店列表获取失败')
|
||||||
} finally {
|
} finally {
|
||||||
this.merchantLoading = false
|
this.merchantLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 门店明细(全量可达 8000+ 条)只放在实例上,不进页面 data。
|
||||||
|
// 一旦放进 data,页面 data 树会膨胀到 1MB+,此后每次 setData 都要重新
|
||||||
|
// diff/序列化整棵树,连只含一个字段的 setData 也会从 ~490ms 涨到 ~1000ms。
|
||||||
|
setMerchantChains(chains) {
|
||||||
|
const list = Array.isArray(chains) ? chains : []
|
||||||
|
this.merchantStore = list.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchants: Array.isArray(chain.merchants) ? chain.merchants : []
|
||||||
|
}))
|
||||||
|
this.merchantChainList = this.merchantStore.map(chain => ({
|
||||||
|
id: chain.id,
|
||||||
|
text: chain.text,
|
||||||
|
merchantCount: chain.merchants.length
|
||||||
|
}))
|
||||||
|
},
|
||||||
async prepareStoreTaskData() {
|
async prepareStoreTaskData() {
|
||||||
await this.getMerchantList()
|
await this.getMerchantList()
|
||||||
this.syncStoreMerchantMeta()
|
this.syncStoreMerchantMeta()
|
||||||
@@ -1157,12 +1187,12 @@ export default {
|
|||||||
let chainIndex = chainList.findIndex(chain => String(chain.id) === String(item && item.chainId !== undefined ? item.chainId : ''))
|
let chainIndex = chainList.findIndex(chain => String(chain.id) === String(item && item.chainId !== undefined ? item.chainId : ''))
|
||||||
if (chainIndex < 0 && item && item.merchantId) {
|
if (chainIndex < 0 && item && item.merchantId) {
|
||||||
chainIndex = chainList.findIndex(chain => {
|
chainIndex = chainList.findIndex(chain => {
|
||||||
const merchants = Array.isArray(chain.merchants) ? chain.merchants : []
|
const merchants = this.getMerchantsByChainId(chain && chain.id)
|
||||||
return merchants.some(merchant => String(merchant.id) === String(item.merchantId))
|
return merchants.some(merchant => String(merchant.id) === String(item.merchantId))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (chainIndex < 0) chainIndex = 0
|
if (chainIndex < 0) chainIndex = 0
|
||||||
const merchants = Array.isArray(chainList[chainIndex].merchants) ? chainList[chainIndex].merchants : []
|
const merchants = this.getMerchantsByChainId(chainList[chainIndex] && chainList[chainIndex].id)
|
||||||
let merchantIndex = merchants.findIndex(merchant => String(merchant.id) === String(item && item.merchantId !== undefined ? item.merchantId : ''))
|
let merchantIndex = merchants.findIndex(merchant => String(merchant.id) === String(item && item.merchantId !== undefined ? item.merchantId : ''))
|
||||||
if (merchantIndex < 0) merchantIndex = 0
|
if (merchantIndex < 0) merchantIndex = 0
|
||||||
return [chainIndex, merchantIndex]
|
return [chainIndex, merchantIndex]
|
||||||
@@ -1194,7 +1224,7 @@ export default {
|
|||||||
if (!Number.isFinite(chainIndex) || chainIndex < 0) chainIndex = 0
|
if (!Number.isFinite(chainIndex) || chainIndex < 0) chainIndex = 0
|
||||||
if (!Number.isFinite(merchantIndex) || merchantIndex < 0) merchantIndex = 0
|
if (!Number.isFinite(merchantIndex) || merchantIndex < 0) merchantIndex = 0
|
||||||
const chain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
const chain = this.merchantChainOptions[chainIndex] || this.merchantChainOptions[0] || {}
|
||||||
const merchants = Array.isArray(chain.merchants) ? chain.merchants : []
|
const merchants = this.getVisibleMerchants(chain)
|
||||||
if (!merchants.length) {
|
if (!merchants.length) {
|
||||||
merchantIndex = 0
|
merchantIndex = 0
|
||||||
} else if (chainIndex !== currentChainIndex || merchantIndex > merchants.length - 1) {
|
} else if (chainIndex !== currentChainIndex || merchantIndex > merchants.length - 1) {
|
||||||
@@ -1211,7 +1241,7 @@ export default {
|
|||||||
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
const chainIndex = Number(this.merchantPickerValue[0] || 0)
|
||||||
const merchantIndex = Number(this.merchantPickerValue[1] || 0)
|
const merchantIndex = Number(this.merchantPickerValue[1] || 0)
|
||||||
const chain = this.merchantChainOptions[chainIndex] || null
|
const chain = this.merchantChainOptions[chainIndex] || null
|
||||||
const merchants = chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
const merchants = this.getVisibleMerchants(chain)
|
||||||
const selected = merchants[merchantIndex] || null
|
const selected = merchants[merchantIndex] || null
|
||||||
if (!selected || selected.id === '' || selected.id === null || selected.id === undefined) return
|
if (!selected || selected.id === '' || selected.id === null || selected.id === undefined) return
|
||||||
const current = this.storeList[index] || this.createStoreItem()
|
const current = this.storeList[index] || this.createStoreItem()
|
||||||
|
|||||||
Reference in New Issue
Block a user