瑶都万能墙
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
4.1 KiB

1 year ago
1 year ago
8 months ago
8 months ago
8 months ago
8 months ago
11 months ago
1 year ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
8 months ago
8 months ago
8 months ago
1 year ago
8 months ago
8 months ago
1 year ago
11 months ago
11 months ago
8 months ago
11 months ago
1 year ago
  1. <template>
  2. <view class="page">
  3. <navbar title="同城群"/>
  4. <!-- 顶部操作栏 -->
  5. <view class="top-actions">
  6. <view class="search-container">
  7. <uv-search
  8. v-model="searchKeyword"
  9. placeholder="搜索群组名称"
  10. @search="onSearch"
  11. @clear="onClear"
  12. bgColor="#f5f5f5"
  13. :showAction="false"
  14. ></uv-search>
  15. </view>
  16. <view class="create-btn" @click="createGroup">
  17. <uv-icon name="plus" size="30rpx" color="#fff"></uv-icon>
  18. <text>创建群组</text>
  19. </view>
  20. </view>
  21. <!-- 城市分类标签 -->
  22. <view class="city-tabs-container">
  23. <uv-tabs
  24. :list="categoryList"
  25. :current="currentCityTabIndex"
  26. :activeStyle="{color: '#5baaff', fontWeight: 600}"
  27. lineColor="#5baaff"
  28. lineHeight="6rpx"
  29. lineWidth="40rpx"
  30. keyName="name"
  31. @click="onCategoryClick"
  32. />
  33. </view>
  34. <!-- 群组列表 -->
  35. <view class="group-list">
  36. <groupItem
  37. :key="index"
  38. v-for="(item, index) in List"
  39. :item="item"
  40. @click="onGroupClick(item)"
  41. />
  42. </view>
  43. <!-- 空状态 -->
  44. <view v-if="List.length === 0 && !loading" class="empty-state">
  45. <uv-empty
  46. mode="list"
  47. text="暂无群组"
  48. iconSize="120"
  49. ></uv-empty>
  50. </view>
  51. <!-- 加载状态 -->
  52. <view v-if="loading" class="loading-state">
  53. <uv-loading-icon size="40"></uv-loading-icon>
  54. <text>加载中...</text>
  55. </view>
  56. <tabber select="2" />
  57. </view>
  58. </template>
  59. <script>
  60. import tabber from '@/components/base/tabbar.vue'
  61. import groupItem from '@/components/list/group/groupItem.vue'
  62. import loadList from '@/mixins/loadList.js'
  63. import { mapState } from 'vuex'
  64. export default {
  65. components : {
  66. tabber,
  67. groupItem,
  68. },
  69. mixins: [loadList],
  70. data() {
  71. return {
  72. searchKeyword: '',
  73. currentCityTabIndex: 0, // uv-tabs当前选中的城市索引
  74. mixinsListApi: 'groupList', // 使用group.js中的groupList接口
  75. }
  76. },
  77. computed: {
  78. ...mapState(['cityList']),
  79. // 城市分类列表(包含"全部"选项)
  80. categoryList() {
  81. const allTab = { name: '全部', value: null }
  82. const cityTabs = this.cityList.map(city => ({
  83. name: city.name || city.cityName || city.title,
  84. value: city.id || city.cityId
  85. }))
  86. return [allTab, ...cityTabs]
  87. }
  88. },
  89. onLoad() {
  90. // 获取城市列表
  91. this.$store.commit('getCityList')
  92. },
  93. methods: {
  94. // 搜索群组
  95. onSearch(keyword) {
  96. this.searchKeyword = keyword
  97. this.queryParams.title = keyword // 使用后端字段名
  98. this.refreshList()
  99. },
  100. // 清除搜索
  101. onClear() {
  102. this.searchKeyword = ''
  103. delete this.queryParams.title
  104. this.refreshList()
  105. },
  106. // 分类点击
  107. onCategoryClick(item) {
  108. this.currentCityTabIndex = item.index
  109. if (item.value) {
  110. // 使用城市ID作为筛选条件
  111. this.queryParams.classId = item.value // 使用后端字段名
  112. } else {
  113. // 选择"全部"时清除城市筛选
  114. delete this.queryParams.classId
  115. }
  116. this.refreshList()
  117. },
  118. // 群组点击
  119. onGroupClick(item) {
  120. // 跳转到群组详情页
  121. this.$utils.navigateTo('/pages_order/group/groupDetail?id=' + item.id)
  122. },
  123. // 创建群组
  124. createGroup() {
  125. this.$utils.navigateTo('/pages_order/group/createGroup')
  126. }
  127. }
  128. }
  129. </script>
  130. <style scoped lang="scss">
  131. .page{
  132. background-color: #f5f5f5;
  133. min-height: 100vh;
  134. .top-actions {
  135. background-color: #fff;
  136. padding: 20rpx;
  137. display: flex;
  138. align-items: center;
  139. gap: 20rpx;
  140. .search-container {
  141. flex: 1;
  142. }
  143. .create-btn {
  144. display: flex;
  145. align-items: center;
  146. background-color: #5baaff;
  147. color: #fff;
  148. padding: 15rpx 20rpx;
  149. border-radius: 30rpx;
  150. font-size: 26rpx;
  151. text {
  152. margin-left: 8rpx;
  153. }
  154. }
  155. }
  156. .category-tabs {
  157. background-color: #fff;
  158. margin-bottom: 20rpx;
  159. }
  160. .group-list {
  161. padding-bottom: 120rpx;
  162. }
  163. .empty-state {
  164. padding: 100rpx 0;
  165. text-align: center;
  166. }
  167. .loading-state {
  168. display: flex;
  169. flex-direction: column;
  170. align-items: center;
  171. justify-content: center;
  172. padding: 100rpx 0;
  173. text {
  174. margin-top: 20rpx;
  175. color: #999;
  176. font-size: 28rpx;
  177. }
  178. }
  179. }
  180. </style>