phone.uvue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <template>
  2. <view class="flex flex-col mb-5">
  3. <cl-text :size="18" :pt="{ className: 'font-bold' }">{{ t("您好,欢迎登录!") }}</cl-text>
  4. <cl-text :pt="{ className: 'mt-2' }" color="info">{{
  5. t("首次登录将自动为您完成注册")
  6. }}</cl-text>
  7. </view>
  8. <view class="flex flex-col">
  9. <view class="mb-3 flex flex-row">
  10. <cl-input
  11. v-model="form.phone"
  12. prefix-icon="device-fill"
  13. :placeholder="t('请输入手机号')"
  14. :border="false"
  15. :pt="{
  16. className: parseClass([
  17. '!h-[45px] flex-1 !rounded-xl !px-4',
  18. [isDark, '!bg-surface-70', '!bg-white']
  19. ]),
  20. prefixIcon: {
  21. className: 'mr-1'
  22. }
  23. }"
  24. ></cl-input>
  25. </view>
  26. <view class="relative flex flex-row items-center mb-5">
  27. <cl-input
  28. v-model="form.smsCode"
  29. :clearable="false"
  30. type="number"
  31. prefix-icon="shield-check-fill"
  32. :placeholder="t('请输入验证码')"
  33. :maxlength="4"
  34. :border="false"
  35. :pt="{
  36. className: parseClass([
  37. '!h-[45px] flex-1 !rounded-xl !px-4',
  38. [isDark, '!bg-surface-70', '!bg-white']
  39. ]),
  40. prefixIcon: {
  41. className: 'mr-1'
  42. }
  43. }"
  44. >
  45. </cl-input>
  46. <view class="absolute right-0">
  47. <sms-btn
  48. :ref="refs.set('smsBtn')"
  49. :phone="form.phone"
  50. @success="showCode = true"
  51. ></sms-btn>
  52. </view>
  53. </view>
  54. <cl-button
  55. :pt="{
  56. className: '!h-[45px] !rounded-xl'
  57. }"
  58. :loading="loading"
  59. :disabled="disabled"
  60. @tap="toLogin"
  61. >
  62. {{ t("登录") }}
  63. </cl-button>
  64. </view>
  65. </template>
  66. <script setup lang="ts">
  67. import { computed, inject, ref, type PropType } from "vue";
  68. import type { LoginForm } from "../../types";
  69. import SmsBtn from "../sms-btn.uvue";
  70. import { isDark, parseClass, request, useRefs, type Response, t } from "@/.cool";
  71. import { useUi } from "@/uni_modules/cool-ui";
  72. const props = defineProps({
  73. form: {
  74. type: Object as PropType<LoginForm>,
  75. default: () => ({})
  76. }
  77. });
  78. const emit = defineEmits(["success"]);
  79. const ui = useUi();
  80. const refs = useRefs();
  81. // 是否同意
  82. const isAgree = inject("isAgree") as () => boolean;
  83. // 是否显示验证码
  84. const showCode = ref(false);
  85. // 是否加载中
  86. const loading = ref(false);
  87. // 是否禁用
  88. const disabled = computed(() => {
  89. return props.form.phone == "" || props.form.smsCode == "";
  90. });
  91. // 登录
  92. async function toLogin() {
  93. if (!isAgree()) {
  94. return;
  95. }
  96. const { phone, smsCode } = props.form;
  97. loading.value = true;
  98. await request({
  99. url: "/app/user/login/phone",
  100. method: "POST",
  101. data: {
  102. phone,
  103. smsCode
  104. }
  105. })
  106. .then((res) => {
  107. emit("success", res);
  108. })
  109. .catch((err) => {
  110. ui.showToast({
  111. message: (err as Response).message!
  112. });
  113. });
  114. loading.value = false;
  115. }
  116. </script>