巴青农资商城

register.vue 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <template>
  2. <view class="auth-page">
  3. <view class="auth-hero">
  4. <view class="auth-hero__brand">
  5. <text class="auth-hero__app">巴青农资商城</text>
  6. <text class="auth-hero__welcome">会员注册</text>
  7. </view>
  8. </view>
  9. <view class="auth-body">
  10. <view class="auth-card">
  11. <text class="auth-card__title">手机号注册</text>
  12. <text class="auth-card__sub">无需短信验证码,设置密码即可注册</text>
  13. <view v-if="!agreement.registrationOpen" class="auth-closed">
  14. <text>{{ agreement.message || '会员注册暂未开放' }}</text>
  15. </view>
  16. <template v-else>
  17. <view class="auth-field">
  18. <view class="auth-field__box">
  19. <u-icon name="phone" color="#6b7f72" size="22" />
  20. <input
  21. v-model="form.mobile"
  22. class="auth-field__input"
  23. type="number"
  24. maxlength="11"
  25. placeholder="请输入手机号"
  26. placeholder-class="auth-field__placeholder"
  27. />
  28. </view>
  29. </view>
  30. <view class="auth-field">
  31. <view class="auth-field__box">
  32. <u-icon name="lock" color="#6b7f72" size="22" />
  33. <input
  34. v-model="form.password"
  35. class="auth-field__input"
  36. type="password"
  37. placeholder="请设置登录密码(至少6位)"
  38. placeholder-class="auth-field__placeholder"
  39. />
  40. </view>
  41. </view>
  42. <view class="auth-field">
  43. <view class="auth-field__box">
  44. <u-icon name="lock-fill" color="#6b7f72" size="22" />
  45. <input
  46. v-model="form.confirmPassword"
  47. class="auth-field__input"
  48. type="password"
  49. placeholder="请再次输入密码"
  50. placeholder-class="auth-field__placeholder"
  51. />
  52. </view>
  53. </view>
  54. <!-- <view class="auth-field">
  55. <view class="auth-field__box">
  56. <u-icon name="account" color="#6b7f72" size="22" />
  57. <input
  58. v-model="form.memberCode"
  59. class="auth-field__input"
  60. type="text"
  61. placeholder="会员名称/会员 ID(选填,不填自动生成)"
  62. placeholder-class="auth-field__placeholder"
  63. />
  64. </view>
  65. </view> -->
  66. <agreement-block
  67. v-model="form.agreementAccepted"
  68. :enabled="agreement.enabled"
  69. :checkbox-label="agreement.checkboxLabel"
  70. :agreement-title="agreement.agreementTitle"
  71. :version-label="agreement.versionLabel"
  72. :content="agreement.content"
  73. />
  74. <view
  75. :class="['auth-btn', { 'auth-btn--loading': loading }]"
  76. :disabled="loading"
  77. @click="handleRegister"
  78. >
  79. <text class="auth-btn__txt">{{ loading ? '提交中…' : '注 册' }}</text>
  80. </view>
  81. </template>
  82. <view class="auth-switch">
  83. <text>已有账号?</text>
  84. <text class="auth-switch__link" @click="goLogin">去登录</text>
  85. </view>
  86. </view>
  87. </view>
  88. </view>
  89. </template>
  90. <script setup>
  91. import { ref, reactive } from 'vue'
  92. import { onLoad } from '@dcloudio/uni-app'
  93. import { memberRegister } from '@/api/member'
  94. import { loadServiceAgreement } from '@/utils/memberAgreement'
  95. import { validateMobile, validatePassword } from '@/utils/memberValidate'
  96. import { PAGE_LOGIN } from '@/utils/pageRoute'
  97. import AgreementBlock from '@/components/account/AgreementBlock.vue'
  98. import { useActionGuard } from '@/utils/actionGuard'
  99. const registerGuard = useActionGuard()
  100. const loading = registerGuard.locked
  101. const agreement = reactive({
  102. enabled: false,
  103. registrationOpen: true,
  104. requireAgreementOnLogin: false,
  105. message: '',
  106. agreementTitle: '',
  107. versionLabel: '',
  108. content: '',
  109. checkboxLabel: ''
  110. })
  111. const form = reactive({
  112. mobile: '',
  113. password: '',
  114. confirmPassword: '',
  115. memberCode: '',
  116. agreementAccepted: false
  117. })
  118. onLoad(async (options) => {
  119. const cfg = await loadServiceAgreement()
  120. Object.assign(agreement, cfg)
  121. if (options && options.mobile) {
  122. form.mobile = decodeURIComponent(options.mobile)
  123. }
  124. })
  125. function goLogin() {
  126. const q = form.mobile ? `?account=${encodeURIComponent(form.mobile.trim())}` : ''
  127. uni.navigateTo({ url: `${PAGE_LOGIN}${q}` })
  128. }
  129. function validateForm() {
  130. const mobileMsg = validateMobile(form.mobile)
  131. if (mobileMsg) {
  132. uni.showToast({ title: mobileMsg, icon: 'none' })
  133. return false
  134. }
  135. const pwdMsg = validatePassword(form.password)
  136. if (pwdMsg) {
  137. uni.showToast({ title: pwdMsg, icon: 'none' })
  138. return false
  139. }
  140. if (form.password !== form.confirmPassword) {
  141. uni.showToast({ title: '两次输入的密码不一致', icon: 'none' })
  142. return false
  143. }
  144. if (agreement.enabled && !form.agreementAccepted) {
  145. uni.showToast({ title: '请先阅读并同意服务协议', icon: 'none' })
  146. return false
  147. }
  148. return true
  149. }
  150. function handleRegister() {
  151. if (!agreement.registrationOpen) return
  152. registerGuard.run(async () => {
  153. if (!validateForm()) return
  154. await memberRegister({
  155. mobile: form.mobile.trim(),
  156. password: form.password,
  157. confirmPassword: form.confirmPassword,
  158. memberCode: (form.memberCode || '').trim() || undefined,
  159. agreementAccepted: agreement.enabled ? form.agreementAccepted : true
  160. })
  161. uni.showToast({ title: '注册成功,请登录', icon: 'none', duration: 2000 })
  162. setTimeout(() => {
  163. goLogin()
  164. }, 1500)
  165. })
  166. }
  167. </script>
  168. <style lang="scss" scoped>
  169. @import '@/styles/auth.scss';
  170. </style>