国外MOSE官网
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.

282 lines
6.2 KiB

4 days ago
4 days ago
4 days ago
4 days ago
4 days ago
4 days ago
4 days ago
4 days ago
4 days ago
4 days ago
4 days ago
4 days ago
  1. <template>
  2. <view class="shop-content">
  3. <!-- 搜索框 -->
  4. <view class="search-container">
  5. <uv-search
  6. v-model="searchValue"
  7. placeholder="搜索商品名"
  8. :show-action="false"
  9. bg-color="#f3f7f8"
  10. inputAlign="center"
  11. height="40"
  12. margin="10rpx"
  13. @search="onSearch"
  14. ></uv-search>
  15. </view>
  16. <!-- Tab栏 -->
  17. <view class="tab-container">
  18. <uv-tabs
  19. :list="tabList"
  20. :current="currentTab"
  21. @change="onTabChange"
  22. active-color="#218CDD"
  23. inactive-color="#999"
  24. line-color="#218CDD"
  25. :line-width="40"
  26. :line-height="4"
  27. font-size="26"
  28. height="80"
  29. ></uv-tabs>
  30. </view>
  31. <!-- 商品列表 -->
  32. <view class="goods-container">
  33. <view class="goods-grid">
  34. <view
  35. class="goods-item"
  36. v-for="(item, index) in goodsList"
  37. :key="index"
  38. @click="onGoodsClick(item)"
  39. >
  40. <view class="goods-image">
  41. <image :src="item.image" mode="aspectFit" class="image"></image>
  42. </view>
  43. <view class="goods-info">
  44. <text class="goods-name">{{ item.title }}</text>
  45. <view class="goods-bottom">
  46. <view class="points-info">
  47. <image src="/static/积分图标.png" class="points-icon" mode="aspectFit"></image>
  48. <text class="points-text">{{ item.price }}积分</text>
  49. </view>
  50. <uv-button
  51. type="primary"
  52. size="mini"
  53. text="立即兑换"
  54. :custom-style="buttonStyle"
  55. @click.stop="onExchange(item)"
  56. ></uv-button>
  57. </view>
  58. </view>
  59. </view>
  60. </view>
  61. </view>
  62. </view>
  63. </template>
  64. <script>
  65. export default {
  66. name: 'ShopContent',
  67. data() {
  68. return {
  69. searchValue: '',
  70. currentTab: 0,
  71. pageNo: 1,
  72. pageSize: 10,
  73. tabList: [
  74. { name: '全部' },
  75. { name: '积分兑换' },
  76. { name: '兑换量' },
  77. { name: '女装' },
  78. { name: '母婴' },
  79. { name: '水果' },
  80. { name: '竹制品' }
  81. ],
  82. goodsList: [],
  83. buttonStyle: {
  84. width: '128rpx',
  85. height: '44rpx',
  86. borderRadius: '28rpx',
  87. fontSize: '22rpx'
  88. }
  89. }
  90. },
  91. computed: {
  92. // filteredGoodsList() {
  93. // let list = this.goodsList
  94. // // 根据搜索关键词过滤
  95. // if (this.searchValue) {
  96. // list = list.filter(item =>
  97. // item.name.toLowerCase().includes(this.searchValue.toLowerCase())
  98. // )
  99. // }
  100. // // 根据tab过滤
  101. // const currentTabName = this.tabList[this.currentTab].name
  102. // if (currentTabName !== '全部') {
  103. // if (currentTabName === '兑换量') {
  104. // // 按兑换量排序
  105. // list = [...list].sort((a, b) => b.exchangeCount - a.exchangeCount)
  106. // } else {
  107. // // 按分类过滤
  108. // list = list.filter(item => item.category === currentTabName)
  109. // }
  110. // }
  111. // return list
  112. // }
  113. },
  114. methods: {
  115. onSearch(value) {
  116. console.log('搜索:', value)
  117. },
  118. onTabChange(index) {
  119. this.currentTab = index
  120. },
  121. onGoodsClick(item) {
  122. // 跳转到商品详情页
  123. uni.navigateTo({
  124. url: `/subPages/shop/goodsDetail?id=${item.id}`
  125. })
  126. },
  127. onExchange(item) {
  128. uni.showModal({
  129. title: '确认兑换',
  130. content: `确定要用${item.points}积分兑换${item.name}吗?`,
  131. success: (res) => {
  132. if (res.confirm) {
  133. // 执行兑换逻辑
  134. uni.showToast({
  135. title: '兑换成功',
  136. icon: 'success'
  137. })
  138. }
  139. }
  140. })
  141. },
  142. async getGoodsList() {
  143. // 实际项目中这里应该调用API
  144. const res = await this.$api.shop.queryGoodsList({
  145. pageNo: this.pageNo,
  146. pageSize: this.pageSize
  147. })
  148. if (res.result.records.length) {
  149. this.goodsList.push(...res.result.records)
  150. this.pageNo++
  151. }else {
  152. uni.showToast({
  153. title: '暂无商品',
  154. icon: 'none'
  155. })
  156. }
  157. },
  158. // 初始化请求参数
  159. initData() {
  160. this.pageNo = 1
  161. this.goodsList = []
  162. }
  163. }
  164. }
  165. </script>
  166. <style lang="scss" scoped>
  167. .shop-content {
  168. background: #f8f8f8;
  169. min-height: calc(100vh - 400rpx);
  170. }
  171. .search-container {
  172. position: sticky;
  173. z-index: 999;
  174. top: 10rpx;
  175. padding: 15rpx 20rpx;
  176. background: #ffffff;
  177. }
  178. .tab-container {
  179. position: sticky;
  180. z-index: 999;
  181. top: 90rpx;
  182. background: #ffffff;
  183. padding: 0 30rpx;
  184. border-bottom: 1rpx solid #f0f0f0;
  185. }
  186. .goods-container {
  187. padding: 20rpx 30rpx;
  188. background: #f8f8f8;
  189. }
  190. .goods-grid {
  191. display: grid;
  192. grid-template-columns: 1fr 1fr;
  193. gap: 20rpx;
  194. }
  195. .goods-item {
  196. display: flex;
  197. flex-direction: column;
  198. background: #ffffff;
  199. border-radius: 12rpx;
  200. padding: 20rpx;
  201. box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
  202. border: 1rpx solid #f5f5f5;
  203. .goods-image {
  204. width: 100%;
  205. height: 230rpx;
  206. border-radius: 8rpx;
  207. overflow: hidden;
  208. margin-bottom: 16rpx;
  209. border: 2rpx dashed #e0e0e0;
  210. .image {
  211. width: 100%;
  212. height: 100%;
  213. object-fit: cover;
  214. }
  215. }
  216. .goods-info {
  217. flex: 1;
  218. display: flex;
  219. flex-direction: column;
  220. .goods-name {
  221. font-size: 28rpx;
  222. color: #333333;
  223. line-height: 1.4;
  224. margin-bottom: 16rpx;
  225. font-weight: 500;
  226. display: -webkit-box;
  227. -webkit-box-orient: vertical;
  228. -webkit-line-clamp: 2;
  229. overflow: hidden;
  230. min-height: 72rpx;
  231. }
  232. .goods-bottom {
  233. display: flex;
  234. // flex-direction: column;
  235. gap: 22rpx;
  236. margin-top: auto;
  237. .points-info {
  238. display: flex;
  239. align-items: center;
  240. .points-icon {
  241. width: 24rpx;
  242. height: 24rpx;
  243. margin-right: 6rpx;
  244. }
  245. .points-text {
  246. font-size: 28rpx;
  247. color: #218CDD;
  248. font-weight: 700;
  249. }
  250. }
  251. }
  252. }
  253. }
  254. </style>