all.vue
5.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
<template>
<view>
<uv-input v-model="searchVal" :placeholder="t('app.common.search')" prefixIconStyle="color:#6d778f" prefixIcon="search" border="none"
customStyle="background-color:#F2F3F6;border-radius:8rpx;padding:8rpx 20rpx;margin: 28rpx"
placeholder-style="font-size:26rpx;color:#6d778f;margin-top:3rpx" />
<uv-index-list :index-list="filteredData.indexList" customNavHeight="100rpx" v-if="filteredData.itemArr.length>0">
<template v-for="(item, index) in filteredData.itemArr">
<!-- #ifdef APP-NVUE -->
<uv-index-anchor height="48rpx" bg-color="#F2F3F6" color="#202328" size="24rpx"
:text="filteredData.indexList[index]"></uv-index-anchor>
<!-- #endif -->
<uv-index-item>
<!-- #ifndef APP-NVUE -->
<uv-index-anchor height="48rpx" bg-color="#F2F3F6" color="#202328" size="24rpx"
:text="filteredData.indexList[index]"></uv-index-anchor>
<!-- #endif -->
<view class="list-cell" v-for="(cell, index) in item" @tap="handleTapCell(cell)">
{{cell.name}}
</view>
</uv-index-item>
</template>
</uv-index-list>
<view class="p-empty" v-else style="margin-top: 280rpx;">
<image class="p-empty-img" v-if="!searchVal" src="/static/common/empty.png" mode=""></image>
<image class="p-empty-img" v-else src="/static/common/no-result.png" mode=""></image>
<text class="p-empty-text">{{ searchVal?t('app.common.noFilterData'):t('maintenance.monitor.project.empty.text') }}</text>
</view>
</view>
</template>
<script setup>
import {
pinyin
} from 'pinyin-pro';
import {
getAccountStoreApi
} from '@/api'
import {
getStageObj
} from '@/utils'
import {
onLoad
} from '@dcloudio/uni-app'
import {
ref,
onMounted,
computed
} from 'vue'
import {
t
} from '@/plugins/index.js'
/****************** 搜索相关 ********************/
const searchVal = ref('')
// 存储原始数据
const originalData = ref({
indexList: [],
itemArr: []
});
// 新增:带搜索过滤的计算属性
const filteredData = computed(() => {
const searchText = searchVal.value.trim().toLowerCase();
// 无搜索值时返回完整数据
if (!searchText) return originalData.value;
const result = {
indexList: [],
itemArr: []
};
originalData.value.indexList.forEach((letter, index) => {
const originItems = originalData.value.itemArr[index];
// 过滤当前字母下的项目
const matchedItems = originItems.filter(oItem => {
return oItem.name.toLowerCase().includes(searchText)
});
// 只保留有匹配项的字母
if (matchedItems.length > 0) {
result.indexList.push(letter);
result.itemArr.push(matchedItems);
}
});
return result;
});
const allStore = ref([])
onLoad(() => {
uni.setNavigationBarTitle({
title: t('DownloadInfo.allStore')
})
getAllStore()
})
// 选中
const handleTapCell = (cell) => {
cell.type = 'store'
uni.$emit('mallSelect', cell)
uni.navigateBack({
delta: 2
})
}
// 获取拼音
const getFullPinYin = (str) => {
if (!str || typeof str !== 'string') return '';
// const firstChar = str.charAt(0);
// const pinyinArr = pinyin(firstChar, {
// toneType: 'none'
// });
const pinyinArr = pinyin(str, {
toneType: 'none',
nonZh: 'consecutive',
type: 'array'
});
return pinyinArr.join('');
// return pinyinArr.length > 0 ? pinyinArr[0] : '';
}
const indexList = ref([])
const itemArr = ref([])
const getAllStore = async () => {
try {
uni.showLoading({
title: '数据加载中...'
})
const account = await getStageObj('account');
const {
data
} = await getAccountStoreApi({
accountId: account.id,
status: 1,
// sortName: 'name',
// sortOrder: 'desc'
});
// 1. 中文拼音排序
const sortedData = [...data].sort((a, b) => {
const pyA = getFullPinYin(a.name);
const pyB = getFullPinYin(b.name);
// const pyA = pinyin(a.name, {
// pattern: 'first',
// toneType: 'none'
// });
// const pyB = pinyin(b.name, {
// pattern: 'first',
// toneType: 'none'
// });
return pyA.localeCompare(pyB);
});
// 2. 生成A-Z字母表
const allLetters = Array.from({
length: 26
}, (_, i) =>
String.fromCharCode(65 + i) // A-Z
);
// 3. 初始化分组容器
const grouped = allLetters.reduce((acc, cur) => {
acc[cur] = [];
return acc;
}, {});
// 4. 数据分组
sortedData.forEach(store => {
const firstChar = pinyin(store.name, {
pattern: 'first',
toneType: 'none',
nonZh: 'consecutive'
}).charAt(0).toUpperCase();
if (/^[A-Z]$/.test(firstChar)) { // 仅处理A-Z
grouped[firstChar].push(store);
}
});
// 5. 过滤空分组并保持字母顺序
const validLetters = allLetters.filter(letter =>
grouped[letter].length > 0
);
originalData.value = {
indexList: validLetters,
itemArr: validLetters.map(letter => grouped[letter])
};
} catch (error) {
console.error("数据处理失败:", error);
return {
indexList: [],
itemArr: []
};
} finally {
uni.hideLoading()
}
};
</script>
<style lang="scss" scoped>
.list-cell {
padding: 0 32rpx 0 28rpx;
height: 68rpx;
line-height: 68rpx;
color: #202328;
font-size: 28rpx;
/* #ifdef APP-NVUE */
lines: 1;
/* #endif */
/* #ifndef APP-NVUE */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
/* #endif */
&:active {
background-color: #f2f3f6;
}
}
</style>