login.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <template>
  2. <view class="container">
  3. <img class="img" src="@/static/images/school-logo.jpg" />
  4. <view class="logo_name">万载三中</view>
  5. <!-- 手机号码输入框区域 -->
  6. <view class="phone">
  7. <input class="phone_input" type="number" placeholder="手机号" placeholder-style="color:#CCCCCC;" v-model="phone" />
  8. </view>
  9. <!-- 验证码区域 -->
  10. <view class="code">
  11. <input class="code_input" type="number" placeholder="验证码" placeholder-style="color:#CCCCCC;" v-model="codeValue" />
  12. <uv-code uniqueKey="login" keepRunning ref="codeDom" @change="codeChange"></uv-code>
  13. <view class="code_box" @click="getCode">{{ tips }}</view>
  14. </view>
  15. <!-- 登录按钮区域 -->
  16. <view class="loginBtn" :class="{ active: btnFlag }" @click="handleLogin">登录</view>
  17. </view>
  18. </template>
  19. <script setup>
  20. import { ref, computed } from 'vue'
  21. import { onLoad } from '@dcloudio/uni-app'
  22. import { myRequest } from '@/utils/api.js'
  23. // 手机号码
  24. const phone = ref('')
  25. // 验证码
  26. const codeValue = ref('')
  27. // 验证码Dom
  28. const codeDom = ref(null)
  29. // 登录按钮是否高亮
  30. const btnFlag = computed(() => {
  31. // 手机号码验证规则
  32. const regPhone = /^1[3-9]\d{9}$/
  33. if (phone.value && regPhone.test(phone.value) && codeValue.value) {
  34. return true
  35. } else {
  36. return false
  37. }
  38. })
  39. // 提示语
  40. const tips = ref('')
  41. onLoad(() => {})
  42. // 获取验证码按钮点击回调
  43. const getCode = async () => {
  44. // 手机号码验证规则
  45. const regPhone = /^1[3-9]\d{9}$/
  46. if (!phone.value) {
  47. uni.showToast({
  48. title: '请先输入手机号码',
  49. icon: 'none'
  50. })
  51. return
  52. }
  53. if (!regPhone.test(phone.value)) {
  54. uni.showToast({
  55. title: '手机号码格式错误',
  56. icon: 'none'
  57. })
  58. return
  59. }
  60. if (codeDom.value.canGetCode) {
  61. const res = await myRequest({
  62. url: '/wanzai/api/wechat/sendMessage',
  63. data: {
  64. phone: phone.value
  65. }
  66. })
  67. // console.log(res)
  68. if (res.code == 200) {
  69. uni.showToast({
  70. title: '验证码已发送',
  71. icon: 'none'
  72. })
  73. codeDom.value.start()
  74. }
  75. } else {
  76. uni.showToast({
  77. title: '倒计时结束后再发送',
  78. icon: 'none'
  79. })
  80. }
  81. }
  82. // 登录按钮回调
  83. const handleLogin = () => {
  84. const flag = verifyValue()
  85. if (flag) {
  86. uni.login({
  87. success: (res) => {
  88. // console.log(res)
  89. getBind(res.code)
  90. }
  91. })
  92. }
  93. }
  94. const getBind = async (wxcode) => {
  95. const res = await myRequest({
  96. url: '/wanzai/api/wechat/vertifyMessage',
  97. data: {
  98. phone: phone.value,
  99. code: codeValue.value,
  100. wxcode
  101. }
  102. })
  103. // console.log(res)
  104. // 1 代表家长 2 代表学生 3 代表老师
  105. uni.setStorageSync('token', res.data.token)
  106. uni.setStorageSync('userInfo', res.data.user)
  107. uni.navigateTo({
  108. url: '/pages/home/home'
  109. })
  110. }
  111. // 验证表格数据是否符合规范
  112. const verifyValue = () => {
  113. // 手机号码验证规则
  114. const regPhone = /^1[3-9]\d{9}$/
  115. if (!phone.value) {
  116. uni.showToast({
  117. title: '请输入手机号',
  118. icon: 'none'
  119. })
  120. return false
  121. }
  122. if (!regPhone.test(phone.value)) {
  123. uni.showToast({
  124. title: '手机号码格式错误',
  125. icon: 'none'
  126. })
  127. return false
  128. }
  129. if (!codeValue.value) {
  130. uni.showToast({
  131. title: '请输入验证码',
  132. icon: 'none'
  133. })
  134. return false
  135. }
  136. return true
  137. }
  138. const codeChange = (text) => {
  139. tips.value = text
  140. }
  141. </script>
  142. <style lang="scss" scoped>
  143. .container {
  144. display: flex;
  145. flex-direction: column;
  146. align-items: center;
  147. min-height: 100vh;
  148. background-color: #f8f8fa;
  149. .img {
  150. margin-top: 120rpx;
  151. width: 200rpx;
  152. height: 200rpx;
  153. border-radius: 20rpx;
  154. }
  155. .logo_name {
  156. margin-top: 25rpx;
  157. font-size: 36rpx;
  158. }
  159. .phone {
  160. box-sizing: border-box;
  161. margin-top: 80rpx;
  162. padding: 0 20rpx;
  163. width: 538rpx;
  164. height: 80rpx;
  165. border-radius: 8rpx;
  166. box-shadow: 0 0 10rpx #ccc;
  167. background-color: #fff;
  168. .phone_input {
  169. height: 100%;
  170. }
  171. }
  172. .code {
  173. display: flex;
  174. justify-content: space-between;
  175. align-items: center;
  176. box-sizing: border-box;
  177. margin-top: 40rpx;
  178. padding: 0 20rpx;
  179. width: 538rpx;
  180. height: 80rpx;
  181. border-radius: 8rpx;
  182. box-shadow: 0 0 10rpx #ccc;
  183. background-color: #fff;
  184. .code_input {
  185. width: 55%;
  186. height: 100%;
  187. }
  188. .code_box {
  189. display: flex;
  190. justify-content: center;
  191. align-items: center;
  192. width: 35%;
  193. height: 80rpx;
  194. color: #3c9cff;
  195. font-size: 26rpx;
  196. }
  197. }
  198. .loginBtn {
  199. display: flex;
  200. justify-content: center;
  201. align-items: center;
  202. margin-top: 50rpx;
  203. width: 538rpx;
  204. height: 80rpx;
  205. color: #a0a1a4;
  206. border-radius: 8rpx;
  207. background-color: #e5e6eb;
  208. }
  209. .active {
  210. color: #fff;
  211. background-color: #0061ff;
  212. }
  213. }
  214. </style>