login.uvue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <template>
  2. <cl-page>
  3. <Back />
  4. <!-- <cl-image src="https://oss.xiaoxiongcode.com/static/home/1.jpg" mode="heightFix" class="w-full h-full object-cover"
  5. height="100%" width="100%" /> -->
  6. <view class="content">
  7. <view class="title">
  8. <cl-image src="https://oss.xiaoxiongcode.com/static/home/logo.png" width="120px" height="120px"
  9. mode="heightFix" />
  10. <cl-text :size="20" color="#666">
  11. 少儿物理启蒙
  12. </cl-text>
  13. </view>
  14. <view class="group">
  15. <view class="w-[80vw]">
  16. <!-- <cl-tabs v-model="val" :list="list" fill :form="formData" @change="tabsChange"></cl-tabs> -->
  17. <cl-form v-model="formData" :pt="{ className: 'mt-1' }">
  18. <view v-if="val === 'quickly_login'">
  19. <phone :form="formData" />
  20. </view>
  21. <view v-else>
  22. <password :form="formData" />
  23. </view>
  24. <view class="flex flex-row items-center justify-center mb-5">
  25. <cl-button :pt="{ className: '!h-[45px] !rounded-full w-[200px] mx-auto' }" :loading="loading"
  26. @tap="toLogin">
  27. 登录
  28. </cl-button>
  29. </view>
  30. </cl-form>
  31. </view>
  32. </view>
  33. <view class="absolute bottom-20 w-full flex flex-row gap-4 items-center justify-center">
  34. <view>
  35. <cl-button type="success" :pt="{ className: '!h-[40px] !rounded-full w-[40px] mx-auto !p-1' }"
  36. :loading="loading" @tap="toWechatLogin">
  37. <cl-image src="https://oss.xiaoxiongcode.com/static/个人中心/微信.png" mode="heightFix" height="20px"
  38. width="auto"></cl-image>
  39. </cl-button>
  40. <view class="mt-1">
  41. <cl-text :size="14" color="#666">
  42. 微信登录
  43. </cl-text>
  44. </view>
  45. </view>
  46. <view v-if="val === 'password'">
  47. <cl-button type="info" :pt="{ className: '!h-[40px] !rounded-full w-[40px] mx-auto !p-1' }" :loading="loading"
  48. @tap="tabsChange('quickly_login')">
  49. <cl-image src="https://oss.xiaoxiongcode.com/static/home/phone.svg" mode="heightFix" height="20px"
  50. width="auto"></cl-image>
  51. </cl-button>
  52. <view class="mt-1">
  53. <cl-text :size="14" color="#666">
  54. 验证码登录
  55. </cl-text>
  56. </view>
  57. </view>
  58. <view v-else>
  59. <cl-button type="info" :pt="{ className: '!h-[40px] !rounded-full w-[40px] mx-auto !p-1' }" :loading="loading"
  60. @tap="tabsChange('password')">
  61. <cl-image src="https://oss.xiaoxiongcode.com/static/home/password.svg" mode="heightFix" height="20px"
  62. width="auto"></cl-image>
  63. </cl-button>
  64. <view class="mt-1">
  65. <cl-text :size="14" color="#666">
  66. 密码登录
  67. </cl-text>
  68. </view>
  69. </view>
  70. </view>
  71. </view>
  72. <cl-action-sheet ref="actionSheetRef">
  73. <template #prepend>
  74. <view class=" mb-3 font-bold text-center">
  75. <cl-text :size="20" color="#666">
  76. 选择登录账号
  77. </cl-text>
  78. </view>
  79. </template>
  80. </cl-action-sheet>
  81. </cl-page>
  82. </template>
  83. <script lang="ts" setup>
  84. import Back from '@/components/back.uvue'
  85. import type { LoginForm } from "./components/types";
  86. import phone from './components/phone.uvue';
  87. import password from './components/password.uvue';
  88. import { ref } from 'vue'
  89. import type { ClTabsItem } from "@/uni_modules/cool-ui";
  90. import { encryptPassword, user, router } from '@/.cool';
  91. import { loginApi, wechatLogin,quicklyRegister } from "@/services/user";
  92. import type { ClActionSheetOptions } from "@/uni_modules/cool-ui";
  93. const actionSheetRef = ref<ClActionSheetComponentPublicInstance | null>(null);
  94. const val = ref('quickly_login')
  95. const list: ClTabsItem[] = [
  96. {
  97. label: '验证码登录',
  98. value: 'quickly_login'
  99. },
  100. {
  101. label: '密码登录',
  102. value: 'password'
  103. },
  104. ]
  105. const formData = ref<LoginForm>({
  106. username: '',
  107. password: '',
  108. randomStr: 0,
  109. grant_type: 'quickly_login',
  110. scope: 'server',
  111. loginType: 99,
  112. code: ''
  113. })
  114. const loading = ref(false)
  115. function tabsChange(type: string) {
  116. val.value = type
  117. if (val.value === 'quickly_login') {
  118. formData.value.code = ''
  119. formData.value.loginType = 99
  120. formData.value.grant_type = 'quickly_login'
  121. formData.value.password = ''
  122. } else {
  123. formData.value.grant_type = 'password'
  124. formData.value.password = ''
  125. formData.value.loginType = 1
  126. formData.value.code = ''
  127. }
  128. }
  129. function toLogin() {
  130. // loading.value = true
  131. console.log(formData.value);
  132. loginApi({
  133. ...formData.value,
  134. password: formData.value.password && encryptPassword(formData.value.password),
  135. }).then(res => {
  136. user.setToken(res)
  137. uni.showToast({
  138. title: '登录成功',
  139. icon: 'success'
  140. })
  141. router.nextLogin();
  142. }).catch(err => {
  143. if(err.message=='手机号不存在'&&val.value==='quickly_login'){
  144. quicklyRegister({
  145. username: formData.value.username,
  146. password: 'ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413',
  147. }).then(res => {
  148. handleSelect(formData.value.username)
  149. })
  150. }else{
  151. uni.showToast({
  152. title: err.message,
  153. icon: 'none'
  154. })
  155. }
  156. })
  157. }
  158. function toWechatLogin() {
  159. uni.login({
  160. provider: 'weixin',
  161. success(res) {
  162. wechatLogin({
  163. code: res.code,
  164. }).then(res => {
  165. console.log(res);
  166. if (res.length === 0) {
  167. uni.showToast({
  168. title: '请先绑定账号',
  169. icon: 'none'
  170. })
  171. return
  172. } else if (res.length === 1) {
  173. handleSelect(res[0])
  174. return
  175. }
  176. const list = res.map(item => ({
  177. label: item,
  178. icon: "user-line",
  179. callback() {
  180. handleSelect(item)
  181. }
  182. }))
  183. actionSheetRef.value!.open({
  184. list: list
  185. } as ClActionSheetOptions);
  186. })
  187. }
  188. })
  189. }
  190. function handleSelect(item: string) {
  191. formData.value.username = item
  192. formData.value.password = 'quickly_login'
  193. formData.value.grant_type = 'quickly_login'
  194. formData.value.loginType = 88
  195. loginApi({
  196. ...formData.value,
  197. }).then(res => {
  198. user.setToken(res)
  199. uni.showToast({
  200. title: '登录成功',
  201. icon: 'success'
  202. })
  203. router.nextLogin();
  204. })
  205. }
  206. </script>
  207. <style lang="scss" scoped>
  208. .content {
  209. @apply w-full h-full;
  210. // 渐变背景
  211. background: linear-gradient(180deg, #169deb5e 0%, #fff 20%);
  212. }
  213. .title {
  214. position: absolute;
  215. top: 10%;
  216. //设置字间距
  217. letter-spacing: 0.1em;
  218. @apply flex flex-col w-full items-center justify-center;
  219. }
  220. .group {
  221. @apply absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white px-4 py-2 pb-10 rounded-xl;
  222. display: flex;
  223. align-items: center;
  224. flex-direction: row;
  225. }
  226. </style>