敢为人鲜小程序前端代码仓库
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.

380 lines
10 KiB

  1. <template>
  2. <view class="wallet-page">
  3. <!-- 导航栏 -->
  4. <navbar title="钱包" leftClick @leftClick="$utils.navigateBack" bgColor="#019245" color="#fff" />
  5. <!-- 总余额展示区 -->
  6. <view class="balance-card" :style="{ backgroundImage: 'url(/static/image/红烧肉.png)' }">
  7. <view class="balance-info">
  8. <view class="balance-title">总余额</view>
  9. <view class="balance-amount">{{ walletData.balance.toFixed(2) }}</view>
  10. <view class="balance-actions">
  11. <view class="action-btn recharge-btn" v-if="!isRecharge" @tap="navigateToRecharge">
  12. <text>去充值</text>
  13. <text class="arrow">></text>
  14. </view>
  15. <view class="action-btn" v-else />
  16. <view class="action-btn detail-btn" @tap="navigateToDetail">
  17. <text>资产明细</text>
  18. <text class="arrow">></text>
  19. </view>
  20. </view>
  21. </view>
  22. </view>
  23. <!-- 提现表单 -->
  24. <view class="withdraw-section">
  25. <view class="section-title">{{ isRecharge ? '我要充值' : '我要提现' }}</view>
  26. <!-- 提现金额输入框 -->
  27. <view class="input-item">
  28. <text class="currency-symbol">¥</text>
  29. <input v-if="!isRecharge" class="amount-input" type="digit" v-model="withdrawAmount" placeholder="请输入提现金额"
  30. @blur="validateAmount" />
  31. <input v-else class="amount-input" type="digit" v-model="rechargeAmount" placeholder="请输入充值金额"
  32. @blur="validateAmount" />
  33. </view>
  34. <!-- 真实姓名输入框 -->
  35. <view class="input-item" v-if="!isRecharge">
  36. <input class="name-input" type="nickname" v-model="realName" placeholder="请输入真实姓名"
  37. @blur="validateName" />
  38. </view>
  39. <!-- 提现说明 -->
  40. <view class="withdraw-notes" v-if="!isRecharge">
  41. <view class="notes-title">提现说明</view>
  42. <view class="notes-list">
  43. <view class="note-item" v-for="(rule, index) in walletData.withdrawRules" :key="index">
  44. <text>{{ index + 1 }}{{ rule }}</text>
  45. </view>
  46. </view>
  47. </view>
  48. </view>
  49. <!-- 提现按钮 -->
  50. <view class="submit-btn-wrapper">
  51. <button class="submit-btn" @tap="submitWithdraw" :disabled="!isFormValid">
  52. {{ isRecharge ? '立即充值' : '立即提现' }}
  53. </button>
  54. </view>
  55. </view>
  56. </template>
  57. <script>
  58. import navbar from '@/components/base/navbar.vue'
  59. import { walletData } from '@/static/js/mockWallet.js'
  60. export default {
  61. components: {
  62. navbar
  63. },
  64. data() {
  65. return {
  66. walletData: null,
  67. withdrawAmount: '',
  68. rechargeAmount: '',
  69. realName: '',
  70. amountError: '',
  71. nameError: '',
  72. isFormValid: true,
  73. isRecharge: false
  74. }
  75. },
  76. onLoad() {
  77. this.walletData = walletData
  78. },
  79. methods: {
  80. // 导航到充值页面
  81. navigateToRecharge() {
  82. this.isRecharge = true
  83. },
  84. // 导航到资产明细页面
  85. navigateToDetail() {
  86. uni.showToast({
  87. title: '资产明细功能暂未开放',
  88. icon: 'error'
  89. })
  90. },
  91. // 验证提现金额
  92. validateAmount() {
  93. if (!this.withdrawAmount) {
  94. this.amountError = '请输入提现金额'
  95. return false
  96. }
  97. const amount = parseFloat(this.withdrawAmount)
  98. if (isNaN(amount) || amount <= 0) {
  99. this.amountError = '请输入有效的提现金额'
  100. return false
  101. }
  102. if (amount > this.walletData.balance) {
  103. this.amountError = '提现金额不能大于余额'
  104. return false
  105. }
  106. if (amount > 200) {
  107. this.amountError = '单笔提现不能超过200元'
  108. return false
  109. }
  110. this.amountError = ''
  111. return true
  112. },
  113. // 验证真实姓名
  114. validateName() {
  115. if (!this.realName) {
  116. this.nameError = '请输入真实姓名'
  117. return false
  118. }
  119. if (this.realName.length < 2) {
  120. this.nameError = '请输入有效的姓名'
  121. return false
  122. }
  123. this.nameError = ''
  124. return true
  125. },
  126. // 提交提现申请
  127. submitWithdraw() {
  128. if (this.isRecharge) {
  129. return this.recharge()
  130. }
  131. // 再次验证表单
  132. if (!this.validateAmount() || !this.validateName()) {
  133. console.log(2);
  134. // 显示具体错误
  135. if (this.amountError) {
  136. console.log(3);
  137. uni.showToast({
  138. title: this.amountError,
  139. icon: 'error'
  140. })
  141. return
  142. }
  143. if (this.nameError) {
  144. uni.showToast({
  145. title: this.nameError,
  146. icon: 'error'
  147. })
  148. return
  149. }
  150. return
  151. }
  152. // 如果在isFormVaild为false的情况下进入函数 则为多次点击 直接返回
  153. if (this.isFormValid) {
  154. this.isFormValid = false
  155. }else return
  156. // 显示提交中状态
  157. uni.showLoading({
  158. title: '提交中...'
  159. })
  160. // 模拟提交过程
  161. setTimeout(() => {
  162. uni.hideLoading()
  163. uni.showToast({
  164. title: '提现申请已提交',
  165. icon: 'success'
  166. })
  167. // 清空表单
  168. this.withdrawAmount = ''
  169. this.realName = ''
  170. // 模拟余额变更
  171. this.walletData.balance -= parseFloat(this.withdrawAmount)
  172. this.isFormValid = true
  173. }, 1500)
  174. },
  175. recharge() {
  176. uni.showModal({
  177. title: '确认充值',
  178. content: '充值金额为' + this.rechargeAmount + '元',
  179. confirmColor: '#019245',
  180. success: (res) => {
  181. // 这里编写函数逻辑
  182. if (res.confirm) {
  183. uni.showLoading({
  184. title: '充值中...'
  185. })
  186. // 执行重置逻辑
  187. // 模拟重置时间
  188. setTimeout(() => {
  189. uni.hideLoading()
  190. uni.showToast({
  191. title: '充值成功',
  192. icon: 'success'
  193. })
  194. // 重置表单
  195. this.rechargeAmount = ''
  196. this.isRecharge = false
  197. }, 1500)
  198. }
  199. },
  200. fail: (err) => {
  201. console.log(err);
  202. }
  203. })
  204. }
  205. }
  206. }
  207. </script>
  208. <style lang="scss" scoped>
  209. .wallet-page {
  210. }
  211. .balance-card {
  212. width: 96%;
  213. height: 280rpx;
  214. background-size: cover;
  215. background-position: center;
  216. padding: 30rpx;
  217. box-sizing: border-box;
  218. position: relative;
  219. margin: 20rpx auto;
  220. border-radius: 20rpx;
  221. .balance-info {
  222. position: relative;
  223. z-index: 2;
  224. color: #fff;
  225. }
  226. .balance-title {
  227. font-size: 28rpx;
  228. margin-bottom: 10rpx;
  229. }
  230. .balance-amount {
  231. font-size: 56rpx;
  232. font-weight: bold;
  233. margin-bottom: 20rpx;
  234. }
  235. .balance-actions {
  236. display: flex;
  237. justify-content: space-between;
  238. // justify-content: center;
  239. align-items: center;
  240. .action-btn {
  241. padding: 10rpx 24rpx;
  242. font-size: 24rpx;
  243. border-radius: 30rpx;
  244. display: flex;
  245. align-items: center;
  246. }
  247. .recharge-btn {
  248. background-color: #fff;
  249. color: $uni-color;
  250. border: none;
  251. min-width: 120rpx;
  252. height: 60rpx;
  253. justify-content: center;
  254. font-size: 24rpx;
  255. font-weight: normal;
  256. gap: 4rpx;
  257. // line-height: 1;
  258. padding: 0 20rpx;
  259. }
  260. .detail-btn {
  261. .arrow {
  262. margin-left: 10rpx;
  263. }
  264. }
  265. }
  266. }
  267. .withdraw-section {
  268. padding: 30rpx;
  269. // background-color: #fff;
  270. .section-title {
  271. font-size: 32rpx;
  272. color: #333;
  273. margin-bottom: 30rpx;
  274. font-weight: bold;
  275. }
  276. .input-item {
  277. display: flex;
  278. align-items: center;
  279. padding: 24rpx 20rpx;
  280. margin-bottom: 20rpx;
  281. background-color: #e7e7e7;
  282. border-radius: 20rpx;
  283. .currency-symbol {
  284. color: #FF0000;
  285. margin-right: 20rpx;
  286. }
  287. .amount-input,
  288. .name-input {
  289. flex: 1;
  290. font-size: 28rpx;
  291. height: 60rpx;
  292. }
  293. .name-input {
  294. padding-left: 40rpx;
  295. }
  296. }
  297. .withdraw-notes {
  298. margin-top: 40rpx;
  299. .notes-title {
  300. font-size: 28rpx;
  301. color: #333;
  302. margin-bottom: 20rpx;
  303. }
  304. .notes-list {
  305. .note-item {
  306. font-size: 26rpx;
  307. color: #666;
  308. line-height: 1.6;
  309. margin-bottom: 10rpx;
  310. }
  311. }
  312. }
  313. }
  314. .submit-btn-wrapper {
  315. padding: 40rpx 30rpx;
  316. .submit-btn {
  317. width: 100%;
  318. height: 88rpx;
  319. background-color: $uni-color;
  320. color: #fff;
  321. font-size: 32rpx;
  322. border-radius: 44rpx;
  323. display: flex;
  324. align-items: center;
  325. justify-content: center;
  326. border: none;
  327. &:disabled {
  328. background-color: #ccc;
  329. color: rgba(255, 255, 255, 0.6);
  330. }
  331. }
  332. }
  333. </style>