index.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <template>
  2. <u-popup :show="show" @close="hideBrandList" mode="right" class="brand_list_popup">
  3. <view class="brand_list_page">
  4. <view class="brand_list">
  5. <u-navbar class="nav-bar" title="品牌" :autoBack="false" :placeholder="true" v-hideNav @leftClick="hideBrandList">
  6. <!-- <view class="u-nav-slot" slot="right" @click="handleAddBrand">
  7. <u-icon name="plus-circle" color="#2979ff" size="20"></u-icon>
  8. <text>新增</text>
  9. </view> -->
  10. </u-navbar>
  11. <u-search placeholder="搜索" v-model="keyword" @custom="handleSearch" @change="handleSearch"></u-search>
  12. <view class="suggest_list">
  13. <view class="brand_item" v-for="item in adviceList" :key="item.id" @click="handleBrandClick(item)">
  14. <image class="brand_img" :src="item.imgUrl ? item.imgUrl : '/static/no-img.png'" alt=""></image>
  15. <view class="brand_name">{{ item.dictLabel }}</view>
  16. </view>
  17. </view>
  18. </view>
  19. <u-index-list :index-list="indexList" class="index_list">
  20. <template v-for="(item, index) in brandList">
  21. <!-- #ifdef APP-NVUE -->
  22. <u-index-anchor :text="indexList[index]"></u-index-anchor>
  23. <!-- #endif -->
  24. <u-index-item>
  25. <!-- #ifndef APP-NVUE -->
  26. <u-index-anchor :text="indexList[index]"></u-index-anchor>
  27. <!-- #endif -->
  28. <view class="list-cell" v-for="cell in item" :key="cell.dictValue" @click="handleBrandClick(cell)">
  29. <image class="brand_img" :src="cell.imgUrl ? cell.imgUrl : '/static/no-img.png'" alt=""></image>
  30. {{ cell.dictLabel }}
  31. </view>
  32. </u-index-item>
  33. </template>
  34. </u-index-list>
  35. <!-- <view class="no_brand">
  36. <u-button type="primary" :plain="true" text="找不到品牌" color="#108cff"></u-button>
  37. </view> -->
  38. </view>
  39. </u-popup>
  40. </template>
  41. <script>
  42. import { chineseToPinYin } from '@/utils/pinyin.js'
  43. export default {
  44. components: {
  45. },
  46. props: {
  47. },
  48. emits: ['selectedBrand'],
  49. data() {
  50. return {
  51. show: false,
  52. keyword: '',
  53. adviceList: [],
  54. indexList: [],
  55. brandList: [],
  56. list: [],
  57. }
  58. },
  59. methods: {
  60. handleSearch(val) {
  61. if(val){
  62. this.filterData(this.list.filter(item => item.dictLabel.includes(this.keyword)))
  63. }else{
  64. this.filterData(this.list)
  65. }
  66. },
  67. handleBrandClick(brand) {
  68. this.$emit('selectedBrand', brand)
  69. this.hideBrandList()
  70. },
  71. // 显示品牌列表
  72. showBrandList() {
  73. this.getList()
  74. this.show = true;
  75. },
  76. // 隐藏品牌列表
  77. hideBrandList() {
  78. this.show = false;
  79. },
  80. getList() {
  81. this.$getDicts('crm_form_brand').then(res => {
  82. this.filterData(res)
  83. this.list = res
  84. this.adviceList = res.filter(item => item.recommend)
  85. })
  86. },
  87. filterData(res){
  88. const processedData = this.processBrandData(res)
  89. this.brandList = processedData.groupedList
  90. this.indexList = processedData.indexList
  91. },
  92. processBrandData(data) {
  93. // 1. 首先按 isDefault 排序(true 的排在前面),然后按 dictLabel 字母排序
  94. const sortedData = data.sort((a, b) => {
  95. // isDefault 为 true 的排在前面
  96. if (a.isDefault !== b.isDefault) {
  97. return b.isDefault - a.isDefault
  98. }
  99. // 如果 isDefault 相同,则按 dictLabel 字母顺序排序
  100. return a.dictLabel.localeCompare(b.dictLabel, 'zh-CN')
  101. })
  102. // 2. 按首字母分组
  103. const groupedData = {}
  104. const indexList = []
  105. for (const item of sortedData) {
  106. let firstLetter
  107. const label = item.dictLabel || ''
  108. if (/[a-zA-Z]/.test(label.charAt(0))) {
  109. // 英文字母开头,使用大写首字母
  110. firstLetter = label.charAt(0).toUpperCase()
  111. } else {
  112. // 中文字符,使用拼音首字母
  113. try {
  114. const pinyin = chineseToPinYin(label)
  115. if (pinyin && pinyin.length > 0 && /[a-zA-Z]/.test(pinyin.charAt(0).toUpperCase())) {
  116. firstLetter = pinyin.charAt(0).toUpperCase()
  117. } else {
  118. firstLetter = '#'
  119. }
  120. } catch (error) {
  121. firstLetter = '#'
  122. }
  123. }
  124. // 创建字母分组
  125. if (!groupedData[firstLetter]) {
  126. groupedData[firstLetter] = []
  127. indexList.push(firstLetter)
  128. }
  129. groupedData[firstLetter].push(item)
  130. }
  131. // 3. 按字母顺序排序索引列表
  132. indexList.sort((a, b) => {
  133. if (a === '#') return 1
  134. if (b === '#') return -1
  135. return a.localeCompare(b)
  136. })
  137. // 4. 将分组数据转换为数组格式
  138. const groupedList = indexList.map(letter => groupedData[letter])
  139. return {
  140. groupedList,
  141. indexList
  142. }
  143. },
  144. }
  145. }
  146. </script>
  147. <style lang="scss" scoped>
  148. @import './index.scss';
  149. </style>