国外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.

328 lines
7.8 KiB

2 days ago
18 hours ago
2 days ago
18 hours ago
2 days ago
18 hours ago
2 days ago
18 hours ago
2 days ago
18 hours ago
2 days ago
18 hours ago
2 days ago
18 hours ago
2 days ago
18 hours ago
2 days ago
18 hours ago
2 days ago
  1. <template>
  2. <view class="exchange-record">
  3. <!-- 自定义tabs -->
  4. <view class="custom-tabs">
  5. <view
  6. v-for="(tab, index) in tabList"
  7. :key="index"
  8. class="tab-item"
  9. @click="tabChange(index)"
  10. >
  11. <text class="tab-text" :class="{ active: currentTab === index }">{{ tab.name }}</text>
  12. <view v-if="currentTab === index" class="tab-line"></view>
  13. </view>
  14. </view>
  15. <!-- 兑换记录列表 -->
  16. <view class="record-list">
  17. <view
  18. v-for="(item, index) in currentRecordList"
  19. :key="index"
  20. class="record-item"
  21. @click="handleItemClick(item)"
  22. >
  23. <image class="record-image" :src="item.image" mode="aspectFit"></image>
  24. <view class="record-content">
  25. <view class="record-info">
  26. <view class="title-row">
  27. <text class="record-title">{{ item.title }}</text>
  28. </view>
  29. <view class="record-points">
  30. <uv-icon name="integral" size="16" color="#218cdd"></uv-icon>
  31. <text class="points-text">{{ item.price }}积分</text>
  32. </view>
  33. <view class="record-time">
  34. <uv-icon name="clock" size="14" color="#999"></uv-icon>
  35. <text class="time-text">兑换时间{{ item.createTime }}</text>
  36. </view>
  37. </view>
  38. <view class="record-action">
  39. <uv-button
  40. v-if="currentTab === 0"
  41. type="primary"
  42. size="small"
  43. text="确认领取"
  44. shape="circle"
  45. @click.stop="viewDetail(item)"
  46. ></uv-button>
  47. <uv-button
  48. v-else-if="currentTab === 1"
  49. type="success"
  50. size="small"
  51. text="查看详情"
  52. shape="circle"
  53. @click.stop="viewDetail(item)"
  54. ></uv-button>
  55. <uv-button
  56. v-else
  57. type="error"
  58. size="small"
  59. text="已取消"
  60. shape="circle"
  61. disabled
  62. ></uv-button>
  63. </view>
  64. </view>
  65. </view>
  66. </view>
  67. </view>
  68. </template>
  69. <script>
  70. export default {
  71. data() {
  72. return {
  73. currentTab: 0,
  74. pageNo: 1,
  75. pageSize: 10,
  76. tabList: [
  77. { name: '待领取' },
  78. { name: '已领取' },
  79. { name: '系统取消' }
  80. ],
  81. // 待领取记录列表
  82. pendingList: [
  83. ],
  84. // 已领取记录列表
  85. receivedList: [
  86. ],
  87. // 系统取消记录列表
  88. cancelledList: [
  89. ]
  90. }
  91. },
  92. computed: {
  93. currentRecordList() {
  94. if (this.currentTab === 0) {
  95. return this.pendingList
  96. } else if (this.currentTab === 1) {
  97. return this.receivedList
  98. } else {
  99. return this.cancelledList
  100. }
  101. }
  102. },
  103. methods: {
  104. tabChange(index) {
  105. this.currentTab = index
  106. this.initData()
  107. this.getOrderList()
  108. },
  109. handleItemClick(item) {
  110. if (this.currentTab === 0) {
  111. this.viewDetail(item)
  112. } else if (this.currentTab === 1) {
  113. this.viewDetail(item)
  114. } else if (this.currentTab === 2) {
  115. this.viewDetail(item)
  116. }
  117. },
  118. confirmReceive(item) {
  119. // 确认领取逻辑
  120. uni.showModal({
  121. title: '确认领取',
  122. content: '确认已领取该商品?',
  123. success: (res) => {
  124. if (res.confirm) {
  125. // 移动到已领取列表
  126. const index = this.pendingList.findIndex(record => record.id === item.id)
  127. if (index !== -1) {
  128. const record = this.pendingList.splice(index, 1)[0]
  129. this.receivedList.unshift(record)
  130. }
  131. uni.showToast({
  132. title: '领取成功',
  133. icon: 'success'
  134. })
  135. }
  136. }
  137. })
  138. },
  139. viewDetail(item) {
  140. // 查看详情逻辑 - 跳转到兑换详情页面
  141. let status = 'pending'
  142. if (this.currentTab === 1) {
  143. status = 'received'
  144. } else if (this.currentTab === 2) {
  145. status = 'cancelled'
  146. }
  147. uni.navigateTo({
  148. url: `/subPages/my/exchangeDetail?id=${item.goodsId}&status=${status}`
  149. })
  150. },
  151. // 清空列表数据
  152. initData() {
  153. this.pageNo = 1
  154. this.pendingList = []
  155. this.receivedList = []
  156. this.cancelledList = []
  157. },
  158. // 获取列表
  159. async getOrderList() {
  160. const res = await this.$api.user.queryOrderList({
  161. pageNo: this.pageNo,
  162. pageSize: this.pageSize,
  163. status: this.currentTab
  164. })
  165. if (res.result.records.length){
  166. if (this.currentTab === 0) {
  167. this.pendingList.push(...res.result.records)
  168. } else if (this.currentTab === 1) {
  169. this.receivedList.push(...res.result.records)
  170. } else {
  171. this.cancelledList.push(...res.result.records)
  172. }
  173. this.pageNo++
  174. }else {
  175. uni.showToast({
  176. title: '暂无数据',
  177. icon: 'none'
  178. })
  179. }
  180. }
  181. },
  182. async onReachBottom() {
  183. await this.getOrderList()
  184. },
  185. async onPullDownRefresh() {
  186. this.initData()
  187. await this.getOrderList()
  188. uni.stopPullDownRefresh()
  189. },
  190. async onShow() {
  191. this.initData()
  192. await this.getOrderList()
  193. }
  194. }
  195. </script>
  196. <style lang="scss" scoped>
  197. .exchange-record {
  198. background-color: #f5f5f5;
  199. min-height: 100vh;
  200. .custom-tabs {
  201. display: flex;
  202. background-color: #fff;
  203. border-bottom: 1rpx solid #e5e5e5;
  204. .tab-item {
  205. flex: 1;
  206. position: relative;
  207. display: flex;
  208. flex-direction: column;
  209. align-items: center;
  210. padding: 30rpx 0;
  211. cursor: pointer;
  212. .tab-text {
  213. font-size: 28rpx;
  214. color: #666;
  215. transition: color 0.3s;
  216. &.active {
  217. color: #218cdd;
  218. font-weight: bold;
  219. }
  220. }
  221. .tab-line {
  222. position: absolute;
  223. bottom: 0;
  224. left: 50%;
  225. transform: translateX(-50%);
  226. width: 60rpx;
  227. height: 4rpx;
  228. background-color: #218cdd;
  229. border-radius: 2rpx;
  230. }
  231. }
  232. }
  233. .record-list {
  234. padding: 20rpx;
  235. .record-item {
  236. display: flex;
  237. align-items: flex-start;
  238. margin-bottom: 30rpx;
  239. background: #fff;
  240. border-radius: 12rpx;
  241. padding: 20rpx;
  242. .record-image {
  243. width: 215rpx;
  244. height: 215rpx;
  245. border-radius: 8rpx;
  246. margin-right: 20rpx;
  247. flex-shrink: 0;
  248. }
  249. .record-content {
  250. flex: 1;
  251. display: flex;
  252. flex-direction: column;
  253. .record-info {
  254. display: flex;
  255. flex-direction: column;
  256. margin-bottom: 20rpx;
  257. .title-row {
  258. margin-bottom: 10rpx;
  259. }
  260. .record-title {
  261. font-size: 22rpx;
  262. // font-weight: bold;
  263. color: #000;
  264. line-height: 1.4;
  265. display: -webkit-box;
  266. -webkit-box-orient: vertical;
  267. -webkit-line-clamp: 2;
  268. overflow: hidden;
  269. }
  270. .record-points {
  271. display: flex;
  272. align-items: center;
  273. margin-bottom: 8rpx;
  274. .points-text {
  275. font-size: 26rpx;
  276. color: #218cdd;
  277. font-weight: bold;
  278. margin-left: 6rpx;
  279. }
  280. }
  281. .record-time {
  282. display: flex;
  283. align-items: center;
  284. .time-text {
  285. font-size: 22rpx;
  286. color: #999;
  287. margin-left: 6rpx;
  288. }
  289. }
  290. }
  291. .record-action {
  292. display: flex;
  293. justify-content: flex-end;
  294. // padding-top: 10rpx;
  295. border-top: 1rpx solid #f0f0f0;
  296. }
  297. }
  298. }
  299. }
  300. }
  301. </style>