wallet.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <template>
  2. <view class="page flex-column">
  3. <navigation-bar
  4. autoFixedStyle="background-color:#fff;"
  5. title="我的钱包"
  6. @ready="ready"
  7. ></navigation-bar>
  8. <view class="head flex-shrink">
  9. <view>
  10. <image class="bg" src="/pages-user/static/wallet-banner.png"></image>
  11. <view class="fg pt-48 pl-48 pr-48">
  12. <view class="flex-align-center">
  13. <uni-icons
  14. type="wallet-filled"
  15. size="24"
  16. color="#ffffff"
  17. ></uni-icons>
  18. <view class="fs-36 color-fff fw-500 ml-16">我的钱包</view>
  19. <view
  20. class="btn flex-center fs-28 ml-auto"
  21. @click="to(`/pages-user/wallet-refund/wallet-refund`)"
  22. >退款</view
  23. >
  24. </view>
  25. <view class="price mt-50" v-if="user">
  26. <text class="color-fff fw-600 fs-48" style="vertical-align: top"
  27. >¥</text
  28. >
  29. <text
  30. class="color-fff fw-600 ml-12"
  31. style="font-size: 46px; line-height: 46px"
  32. >{{ user.balance }}</text
  33. >
  34. </view>
  35. </view>
  36. </view>
  37. </view>
  38. <view class="body flex-grow flex-column">
  39. <view class="tabs flex-shrink flex-align-center">
  40. <view
  41. v-for="(item, index) in tabs"
  42. :key="index"
  43. class="flex-align-center fs-30 mr-60"
  44. :style="{
  45. color:
  46. tab === item.value ? 'rgba(0, 0, 0, 1);' : 'rgba(0, 0, 0, 0.6);',
  47. }"
  48. @click="changeTab(index)"
  49. >{{ item.label
  50. }}<view
  51. :style="{ opacity: tab === item.value ? '1' : '0' }"
  52. class="active"
  53. ></view
  54. ></view>
  55. </view>
  56. <view class="list pl-30 pr-30">
  57. <view
  58. class="item flex-align-center"
  59. v-for="(item, index) in infiniteScroller.list"
  60. :key="index"
  61. @click="detail(index)"
  62. >
  63. <view>
  64. <view class="fs-30 fw-500" key="title" duration="300">{{
  65. typeMap[item.type - 1]
  66. }}</view>
  67. <view class="fs-24" style="color: rgba(0, 0, 0, 0.4)">余额</view>
  68. </view>
  69. <view class="ml-auto" style="text-align: right">
  70. <view class="fs-30 fw-500">
  71. <text>{{ item.type > 1 ? "- " : "" }}{{ item.amount }}</text>
  72. <text class="fs-24 ml-6">元</text>
  73. </view>
  74. <view class="fs-24" style="color: rgba(0, 0, 0, 0.4)">{{
  75. item.transactionTime
  76. }}</view>
  77. </view>
  78. <view class="ml-32" v-if="item.type === 3">
  79. <uni-icons
  80. type="right"
  81. size="12"
  82. color="rgba(0,0,0,0.4)"
  83. ></uni-icons>
  84. </view>
  85. </view>
  86. </view>
  87. <view style="height: 170rpx"></view>
  88. </view>
  89. <style-bottom-view background="#ffffff">
  90. <view class="pl-40 pr-40 pb-30 pt-30">
  91. <style-button
  92. type="primary"
  93. @click="to(`/pages-user/wallet-recharge/wallet-recharge`)"
  94. >充值</style-button
  95. >
  96. </view>
  97. </style-bottom-view>
  98. </view>
  99. </template>
  100. <script setup lang="ts">
  101. import { useInfiniteScroll } from "../../utils/infinite-scroll";
  102. import { onLoad, onReachBottom, onPullDownRefresh } from "@dcloudio/uni-app";
  103. import { fetchWallet } from "../../api/user";
  104. import { to } from "../../utils/navigate";
  105. import { ref } from "vue";
  106. import { rpxToPx } from "@/utils/device";
  107. const user = ref();
  108. const tab = ref(0);
  109. const tabs = ref([
  110. {
  111. label: "全部",
  112. value: 0,
  113. },
  114. {
  115. label: "充值",
  116. value: 1,
  117. },
  118. {
  119. label: "消费",
  120. value: 3,
  121. },
  122. {
  123. label: "退款",
  124. value: 2,
  125. },
  126. ]);
  127. const typeMap = ref(["充值", "提现", "消费"]);
  128. const infiniteScroller = useInfiniteScroll(10, (page) => {
  129. return fetchWallet(tab.value, page, 10).then((res: any) => {
  130. if (res && res.length) {
  131. res.forEach((item: any) => {
  132. item.amount = (Number(item.amount) / 100).toFixed(2);
  133. });
  134. }
  135. return res;
  136. });
  137. });
  138. const scrollViewHeight = ref(0);
  139. onLoad(() => {
  140. infiniteScroller.refresh();
  141. if (getApp<any>().globalData.user) {
  142. user.value = getApp<any>().globalData.user;
  143. }
  144. });
  145. onReachBottom(() => {
  146. infiniteScroller.next();
  147. });
  148. onPullDownRefresh(() => {
  149. infiniteScroller.refresh();
  150. });
  151. const ready = (e: any) => {
  152. scrollViewHeight.value =
  153. getApp<any>().globalData.device.windowHeight -
  154. (e.detail.navigationBarHeight + rpxToPx(380));
  155. };
  156. const changeTab = (index: number) => {
  157. tab.value = tabs.value[index].value;
  158. infiniteScroller.refresh();
  159. };
  160. const detail = (index: number) => {
  161. if (!infiniteScroller.list) {
  162. return;
  163. }
  164. if (infiniteScroller.list[index].type === 3) {
  165. uni.navigateTo({
  166. url: `/pages-charge/order/order?id=${infiniteScroller.list[index].orderNo}`,
  167. });
  168. }
  169. };
  170. </script>
  171. <style lang="scss">
  172. .page {
  173. height: 100vh;
  174. width: 100vw;
  175. background: linear-gradient(
  176. 180deg,
  177. #e0ebff 0%,
  178. rgba(255, 255, 255, 0) 60.13%
  179. );
  180. .head {
  181. padding: 30rpx 40rpx;
  182. & > view {
  183. position: relative;
  184. height: 320rpx;
  185. border-radius: 40rpx;
  186. overflow: hidden;
  187. .bg {
  188. height: 100%;
  189. width: 100%;
  190. }
  191. .fg {
  192. position: absolute;
  193. left: 0px;
  194. top: 0px;
  195. height: 100%;
  196. width: 100%;
  197. .btn {
  198. width: 120rpx;
  199. height: 64rpx;
  200. border-radius: 40rpx;
  201. background: rgba(255, 255, 255, 0.3);
  202. color: #076370;
  203. }
  204. }
  205. }
  206. }
  207. .body {
  208. .tabs {
  209. padding: 0 40rpx;
  210. & > view {
  211. position: relative;
  212. height: 72rpx;
  213. .active {
  214. position: absolute;
  215. left: 50%;
  216. bottom: 0px;
  217. transform: translateX(-50%);
  218. width: 40rpx;
  219. height: 4rpx;
  220. border-radius: 4rpx;
  221. background-color: var(--color-primary);
  222. }
  223. }
  224. }
  225. .list {
  226. .item {
  227. height: 170rpx;
  228. border-bottom: 1rpx solid rgba(0, 0, 0, 0.1);
  229. &:last-child {
  230. border-bottom: none;
  231. }
  232. }
  233. }
  234. }
  235. }
  236. </style>