index.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <script setup>
  2. // import { description, version } from '@root/package.json'
  3. import Agreement from './components/agreement.vue'
  4. import { useMessage } from 'wot-design-uni'
  5. const userStore = useOutsideUserStore()
  6. const router = useRouter()
  7. const message = useMessage('wd-message-box-slot')
  8. const agreed = ref(false)
  9. const isLoading = ref(false)
  10. const agreementVisible = ref(false)
  11. const appName = 'uni-preset-vue-vite'
  12. async function onLoginClick() {
  13. if (!agreed.value) {
  14. uni.showToast({
  15. title: '请先同意服务协议',
  16. icon: 'none'
  17. })
  18. return
  19. }
  20. try {
  21. isLoading.value = true
  22. await userStore.login()
  23. uni.showToast({
  24. title: '登录成功',
  25. icon: 'success'
  26. })
  27. setTimeout(async () => {
  28. router.pushTab({
  29. path: '/pages/index/index'
  30. })
  31. }, 500)
  32. } catch (error) {
  33. uni.showToast({
  34. title: '登录失败,请重试',
  35. icon: 'error'
  36. })
  37. } finally {
  38. isLoading.value = false
  39. }
  40. }
  41. function toggleAgreement() {
  42. agreed.value = !agreed.value
  43. }
  44. function onAgreementClick() {
  45. agreementVisible.value = true
  46. message.alert({
  47. title: '《产品服务协议》'
  48. })
  49. // uni.showModal({
  50. // title: '提示',
  51. // content: '触发了路由中间件,是否允许通过?',
  52. // success: (res) => {}
  53. // })
  54. }
  55. </script>
  56. <template>
  57. <view class="relative min-h-screen overflow-hidden from-blue-50 to-blue-100/70 bg-gradient-to-br">
  58. <view class="absolute left-0 top-0 h-full w-full opacity-5">
  59. <view class="absolute right-10 top-20 h-32 w-32 rounded-full bg-blue-400 blur-3xl"></view>
  60. <view class="absolute bottom-40 left-10 h-24 w-24 rounded-full bg-blue-400 blur-2xl"></view>
  61. </view>
  62. <view class="relative z-10 min-h-screen flex flex-col">
  63. <view class="flex flex-1 flex-col justify-center px-6 py-12">
  64. <view class="mb-12 text-center">
  65. <view class="relative mb-6 inline-block">
  66. <view
  67. class="mx-auto h-24 w-24 flex items-center justify-center rounded-3xl bg-white shadow-lg"
  68. >
  69. <image src="/static/logo.png" alt="App Logo" class="h-16 w-16 rounded-2xl" />
  70. </view>
  71. <view
  72. class="absolute rounded-3xl from-blue-400 to-blue-400 bg-gradient-to-r opacity-20 blur-lg -inset-2"
  73. ></view>
  74. </view>
  75. <view class="space-y-2">
  76. <text class="block text-3xl text-gray-900 font-bold">
  77. {{ appName }}
  78. </text>
  79. <!-- <text class="block text-base text-gray-600">
  80. {{ description }}
  81. </text> -->
  82. </view>
  83. </view>
  84. <view class="space-y-6">
  85. <button
  86. class="relative w-full overflow-hidden rounded-2xl from-blue-500 to-blue-400 bg-gradient-to-r px-6 py-4 font-semibold shadow-lg transition-all duration-200 active:scale-98 disabled:cursor-not-allowed !text-white disabled:opacity-70"
  87. :class="{ 'shadow-xl': !isLoading }"
  88. :disabled="isLoading"
  89. @click="onLoginClick"
  90. >
  91. <view class="flex items-center justify-center space-x-3">
  92. <view v-if="isLoading" class="i-carbon-fade h-5 w-5 animate-spin bg-white"></view>
  93. <view v-else class="i-carbon-phone h-5 w-5"></view>
  94. <text>{{ isLoading ? '登录中...' : '手机号快捷登录' }}</text>
  95. </view>
  96. <view
  97. class="absolute inset-0 from-transparent via-white to-transparent bg-gradient-to-r opacity-0 transition-all duration-500 -translate-x-full group-active:translate-x-full group-active:opacity-20"
  98. ></view>
  99. </button>
  100. <view class="flex items-center px-2 space-x-2">
  101. <view
  102. class="h-5 w-5 flex flex-shrink-0 items-center justify-center border-2 border-gray-300 rounded transition-all duration-200 active:scale-95"
  103. :class="agreed ? 'bg-blue-500 border-blue-500' : 'bg-white'"
  104. @click="toggleAgreement"
  105. >
  106. <view v-if="agreed" class="i-carbon-checkmark h-3 w-3 text-white"></view>
  107. </view>
  108. <view class="mt-[1px] flex-1 leading-relaxed">
  109. <text class="text-sm text-gray-600">
  110. 我已阅读并同意
  111. <text
  112. class="text-blue-600 font-medium transition-colors duration-200 active:text-blue-700"
  113. @click.stop="onAgreementClick"
  114. >
  115. 《产品服务协议》
  116. </text>
  117. </text>
  118. </view>
  119. </view>
  120. </view>
  121. </view>
  122. <view class="px-6 pb-8">
  123. <view class="text-center space-y-3">
  124. <view class="mb-6 flex items-center space-x-4">
  125. <view class="h-px flex-1 bg-gray-200"></view>
  126. <text class="px-3 text-xs text-gray-400"> 技术支持 </text>
  127. <view class="h-px flex-1 bg-gray-200"></view>
  128. </view>
  129. <view class="flex items-center justify-center text-xs text-gray-400 space-x-2">
  130. <view class="i-carbon-information h-3 w-3"></view>
  131. <text>版本 v1.0.0</text>
  132. </view>
  133. </view>
  134. </view>
  135. </view>
  136. </view>
  137. <!-- demo 基础用法 -->
  138. <wd-message-box selector="wd-message-box-slot">
  139. <Agreement />
  140. </wd-message-box>
  141. </template>
  142. <style scoped lang="scss">
  143. @keyframes float {
  144. 0%,
  145. 100% {
  146. transform: translateY(0px);
  147. }
  148. 50% {
  149. transform: translateY(-10px);
  150. }
  151. }
  152. .animate-float {
  153. animation: float 3s ease-in-out infinite;
  154. }
  155. @keyframes spin {
  156. from {
  157. transform: rotate(0deg);
  158. }
  159. to {
  160. transform: rotate(360deg);
  161. }
  162. }
  163. .animate-spin {
  164. animation: spin 1s linear infinite;
  165. }
  166. </style>