wallet-recharge.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <template>
  2. <view class="pl-30 pr-30">
  3. <view class="pay">
  4. <view class="title pt-30 pb-30">充值金额</view>
  5. <view class="flex-wrap">
  6. <view
  7. :class="[
  8. 'option',
  9. 'flex-center',
  10. `option-${index === payOption && !payValue ? 'active' : ''}`,
  11. ]"
  12. v-for="(item, index) in payOptions"
  13. :key="index"
  14. @click="changeOption(index)">
  15. <image
  16. v-if="payOptionsDiscount[index]"
  17. src="/static/images/coupon-center.png"
  18. mode="widthFix"
  19. class="tag fs-24 color-fff fw-500 width-40"
  20. />
  21. <!-- <view
  22. class="tag fs-24 color-fff fw-500"
  23. v-if="payOptionsDiscount[index]">{{ payOptionsDiscount[index] }}
  24. </view>-->
  25. {{ item }}
  26. </view>
  27. </view>
  28. <view v-if="activityStationList&&activityStationList.length>0" class="flex-align-center" @click="handleShowActivityStationDialog">
  29. <view class="fs-30 color-666 pd-10" style="padding: 10px 0;">
  30. 活动站点:{{activityStationList[0]}}
  31. </view>
  32. <view
  33. v-if="activityStationList.length>1"
  34. class="ml-12 color-primary fs-30">
  35. <text>更多</text>
  36. </view>
  37. </view>
  38. <view v-if="payOptionsDiscountDay[payOption]" class="flex-align-center">
  39. <view class="fs-30 color-666">
  40. {{ (payOptionsDiscount[payOption] && payOptionsDiscount[payOption] > 0) ? `享服务费${payOptionsDiscount[payOption]}折,` : '' }}权益有效期{{
  41. payOptionsDiscountDay[payOption]
  42. }}天
  43. </view>
  44. <view
  45. class="ml-12 color-primary fs-30"
  46. @click="to(`/pages-common/activity/activity?id=${activityId}`)">
  47. <text>详细规则</text>
  48. <text class="fs-24 ml-6">>></text>
  49. </view>
  50. </view>
  51. <view class="title pt-60 pb-30">自定义金额</view>
  52. <style-input
  53. :value="payValue > 0 ? payValue : ''"
  54. title="金额"
  55. type="digit"
  56. @input="input"/>
  57. </view>
  58. </view>
  59. <style-dialog
  60. v-if="stationVisible"
  61. title="活动站点"
  62. @close="stationVisible=false">
  63. <view class="activity-station">
  64. <view v-for="station in activityStationList" :key="station" class="activity-station-item">
  65. <text>{{station}}</text>
  66. </view>
  67. </view>
  68. </style-dialog>
  69. <style-bottom-view v-if="!stationVisible">
  70. <view class="pl-60 pr-60 pb-20">
  71. <style-button size="small" type="primary" @click="debounceConfirm">充值</style-button>
  72. </view>
  73. </style-bottom-view>
  74. </template>
  75. <script setup lang="ts">
  76. import {ref} from "vue";
  77. import {fetchProfile, insertMoney} from "../../api/user";
  78. import {onLoad} from "@dcloudio/uni-app";
  79. import {back, to} from "@/utils/navigate";
  80. import {debounce} from "@/utils/util";
  81. import StyleDialog from "@/components/style-dialog/style-dialog.vue";
  82. const balance = ref(0);
  83. const payOption = ref(3);
  84. const payOptions = ref([30, 50, 100, 200, 500, 1000]);
  85. const payOptionsDiscount = ref(["", "", "", "", "", ""]);
  86. const payOptionsDiscountDay = ref([0, 0, 0, 0, 0, 0]);
  87. const payValue = ref(0);
  88. const activityId = ref();
  89. const rechargeRightsId = ref();
  90. const rechargeRightsList = ref([]);
  91. const needBack = ref(false);
  92. const activityStationList = ref([]);
  93. const stationVisible = ref(false)
  94. const handleShowActivityStationDialog = () => {
  95. console.log(stationVisible)
  96. if(activityStationList.value&&activityStationList.value.length>0){
  97. stationVisible.value = true;
  98. console.log(stationVisible)
  99. }
  100. }
  101. const input = (e: any) => {
  102. payValue.value = e.value;
  103. rechargeRightsId.value = 0;
  104. };
  105. const changeOption = (index: number) => {
  106. payValue.value = 0;
  107. payOption.value = index;
  108. let find = rechargeRightsList.value.find((k:any) => (k.amountMin || 0) / 100 === payOptions.value[index]);
  109. if (find) {
  110. rechargeRightsId.value = find?.id;
  111. }
  112. };
  113. const debounceConfirm = debounce(() => {
  114. confirm();
  115. }, 500)
  116. const confirm = () => {
  117. if (payValue.value && !/^[0-9]*(\.\d{1,2})?$/.test(`${payValue.value}`)) {
  118. uni.showModal({
  119. title: "温馨提示",
  120. content: "请输入正确的金额",
  121. showCancel: false,
  122. confirmColor: "#2d9e95",
  123. });
  124. return;
  125. }
  126. const params = payValue.value
  127. ? Number(payValue.value)
  128. : payOptions.value[payOption.value];
  129. if (params > 10000 || params <= 0) {
  130. uni.showModal({
  131. title: "温馨提示",
  132. content: "每次最大充值金额10000,请修改金额",
  133. showCancel: false,
  134. confirmColor: "#2d9e95",
  135. });
  136. return;
  137. }
  138. uni.showLoading({
  139. title: "加载中",
  140. });
  141. insertMoney(params, rechargeRightsId.value)
  142. .then(() => {
  143. return fetchProfile();
  144. })
  145. .then((res) => {
  146. payValue.value = 0;
  147. balance.value = res.balance;
  148. uni.hideLoading();
  149. uni.showToast({
  150. title: "已支付",
  151. icon: "success",
  152. });
  153. setTimeout(() => {
  154. if (needBack.value) {
  155. back();
  156. } else {
  157. to("/pages-user/wallet/wallet");
  158. }
  159. }, 2000);
  160. })
  161. .catch((err) => {
  162. if (/cancel/.test(err.errMsg)) {
  163. return;
  164. }
  165. uni.showModal({
  166. content: `${err.errMsg},请重试`,
  167. });
  168. });
  169. };
  170. onLoad((options: any) => {
  171. console.log(options)
  172. if (options.value) {
  173. payOption.value = payOptions.value.findIndex(
  174. (item) => item === Number((Number(options.value) / 100).toFixed(2))
  175. );
  176. needBack.value = !!options.back;
  177. }
  178. if (options.discount) {
  179. payValue.value = Number((Number(options.discount) / 100).toFixed(2));
  180. }
  181. fetchProfile().then((res) => {
  182. // console.log(res);
  183. balance.value = res.balance;
  184. if (res && res.activityList && res.activityList.length) {
  185. let stationList = res.activityList[0].stationList;
  186. if(stationList&&stationList.length>0){
  187. activityStationList.value = stationList.map(k=>k.stationName)
  188. }
  189. res.activityList[0].rechargeRightsList.forEach((item: any) => {
  190. const val = Number((Number(item.amountMin) / 100).toFixed(2));
  191. const fi = payOptions.value.findIndex((o) => o === val);
  192. if (fi >= 0) {
  193. payOptionsDiscount.value[fi] = ((item.discount || 0) / 10).toFixed(1);
  194. payOptionsDiscountDay.value[fi] = item.validity > 0 ? item.validity : 1;
  195. }
  196. });
  197. if (res.activityList && res.activityList[0].rechargeRightsList && res.activityList[0].rechargeRightsList.length > 0) {
  198. rechargeRightsList.value = res?.activityList[0]?.rechargeRightsList
  199. }
  200. activityId.value = res.activityList[0].id;
  201. }
  202. });
  203. });
  204. </script>
  205. <style lang="scss">
  206. .pay {
  207. .title {
  208. font-weight: 500;
  209. font-size: 32rpx;
  210. color: #000;
  211. }
  212. .option {
  213. position: relative;
  214. width: 214rpx;
  215. height: 140rpx;
  216. background: var(--color-sec);
  217. border-radius: 10rpx;
  218. margin-left: 20rpx;
  219. margin-bottom: 20rpx;
  220. font-size: 36rpx;
  221. color: #000;
  222. font-weight: 500;
  223. //overflow: hidden;
  224. &:nth-child(3n + 1) {
  225. margin-left: 0;
  226. }
  227. .tag {
  228. position: absolute;
  229. top: -9px;
  230. right: -10px;
  231. padding: 2rpx 2rpx;
  232. }
  233. }
  234. .option-active {
  235. color: var(--color-primary);
  236. //border-color: var(--color-primary);
  237. //color: #fff;
  238. font-weight: 700;
  239. }
  240. }
  241. .activity-station{
  242. min-height: 450px;
  243. width: 100%;
  244. background-color: #f6f7fa;
  245. display: flex;
  246. flex-direction: column;
  247. align-items: center;
  248. align-content: center;
  249. &-item{
  250. margin: 8rpx 0;
  251. font-size: 15px;
  252. }
  253. }
  254. </style>