index.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <script setup lang="ts">
  2. import type { MemberVO } from '@/api/globals'
  3. import router from '@/router'
  4. definePage({
  5. name: 'login',
  6. islogin: false,
  7. style: {
  8. navigationBarTitleText: '登录',
  9. navigationStyle: 'custom',
  10. },
  11. })
  12. const StaticUrl = import.meta.env.VITE_STATIC_BASE_URL
  13. // 表单数据
  14. const phone = ref('')
  15. const code = ref('')
  16. // 验证码倒计时
  17. const countdown = ref(0)
  18. const isSending = ref(false)
  19. const { token, redirectName, userInfo } = storeToRefs(useUserStore())
  20. const tabList = ['/pages/order/index', '/pages/voucher/index', '/pages/index/index']
  21. // 发送验证码
  22. async function handleSendCode() {
  23. if (!phone.value) {
  24. useGlobalToast().show('请输入手机号')
  25. return
  26. }
  27. if (!/^1[3-9]\d{9}$/.test(phone.value)) {
  28. useGlobalToast().show('请输入正确的手机号')
  29. return
  30. }
  31. if (isSending.value)
  32. return
  33. isSending.value = true
  34. countdown.value = 60
  35. const timer = setInterval(() => {
  36. countdown.value--
  37. if (countdown.value <= 0) {
  38. clearInterval(timer)
  39. isSending.value = false
  40. }
  41. }, 1000)
  42. // TODO: 调用发送验证码接口
  43. await Apis.general.post_smqjh_auth_api_v1_auth_sms_code({ params: { mobile: phone.value } })
  44. useGlobalToast().show('验证码已发送')
  45. }
  46. // 登录
  47. async function handleLogin() {
  48. if (!phone.value) {
  49. useGlobalToast().show('请输入手机号')
  50. return
  51. }
  52. if (!code.value) {
  53. useGlobalToast().show('请输入验证码')
  54. return
  55. }
  56. uni.showLoading({ mask: true })
  57. try {
  58. const res = await Apis.general.post_smqjh_auth_oauth2_token({ params: { grant_type: 'sms_code', mobile: phone.value, code: code.value } })
  59. uni.hideLoading()
  60. token.value = `Bearer ${res.data.access_token}`
  61. useGlobalToast().show('登录成功')
  62. const user = await Apis.general.get_smqjh_system_app_api_v1_members_me()
  63. userInfo.value = user.data as MemberVO
  64. setTimeout(() => {
  65. if (tabList.includes(redirectName.value)) {
  66. router.pushTab({ path: redirectName.value })
  67. }
  68. else {
  69. router.replace({ path: redirectName.value })
  70. }
  71. }, 1000)
  72. }
  73. catch {
  74. uni.hideLoading()
  75. }
  76. }
  77. </script>
  78. <template>
  79. <view class="login-page min-h-100vh px48rpx">
  80. <view class="w-full flex items-center justify-center pt40rpx">
  81. <image
  82. :src="`${StaticUrl}/smqjh-logo.png`"
  83. class="h120rpx w120rpx"
  84. />
  85. </view>
  86. <!-- 表单区域 -->
  87. <view class="pt242rpx">
  88. <!-- 手机号 -->
  89. <view class="mb48rpx">
  90. <view class="mb24rpx text-32rpx text-#333 font-medium">
  91. 手机号
  92. </view>
  93. <view class="h96rpx flex items-center rounded-48rpx bg-#E5E8D8 px32rpx">
  94. <input
  95. v-model="phone"
  96. type="number"
  97. :maxlength="11"
  98. placeholder="请输入手机号"
  99. placeholder-class="text-#999"
  100. class="flex-1 text-32rpx"
  101. >
  102. </view>
  103. </view>
  104. <!-- 验证码 -->
  105. <view class="mb64rpx">
  106. <view class="mb24rpx text-32rpx text-#333 font-medium">
  107. 验证码
  108. </view>
  109. <view class="h96rpx flex items-center rounded-48rpx bg-#E5E8D8 px32rpx">
  110. <input
  111. v-model="code"
  112. type="tel"
  113. :maxlength="4"
  114. placeholder="请输入验证码"
  115. placeholder-class="text-#999"
  116. class="flex-1 text-32rpx"
  117. >
  118. <view
  119. class="ml20rpx flex-shrink-0 text-28rpx"
  120. :class="[isSending ? 'text-#999' : 'text-#7CB305']"
  121. @click="handleSendCode"
  122. >
  123. {{ isSending ? `${countdown}秒后重新发送` : '获取验证码' }}
  124. </view>
  125. </view>
  126. </view>
  127. <!-- 登录按钮 -->
  128. <wd-button block size="large" @click="handleLogin">
  129. 登录
  130. </wd-button>
  131. <view class="mt20rpx text-center text-#999">
  132. 请使用市民请集合小程序账号进行登录
  133. </view>
  134. </view>
  135. </view>
  136. </template>
  137. <style lang="scss" scoped>
  138. .login-page {
  139. background: linear-gradient( 180deg, #F3FFD1 0%, #FFFFFF 37.42%, #F3FFD1 100%);
  140. }
  141. </style>