LoginPop.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. <script setup>
  2. import { onMounted,onUnmounted,reactive,ref} from 'vue';
  3. import { ElMessage } from 'element-plus';
  4. import {ArrowDown} from '@element-plus/icons-vue'
  5. import {apiUserLogin,apiGetEmailCode,apiGetSMSCode} from '@/api/common'
  6. let sendCodeInterval=null
  7. let phoneAreaList=ref([
  8. {
  9. name: "大陆+86",
  10. value: "86",
  11. },
  12. {
  13. name: "香港+852",
  14. value: "852",
  15. },
  16. {
  17. name: "台湾+886",
  18. value: "886",
  19. },
  20. {
  21. name: "美国+1",
  22. value: "1",
  23. },
  24. {
  25. name: "新加坡+65",
  26. value: "65",
  27. }
  28. ])
  29. let selectArea=ref({name: "大陆+86",value:'86'})
  30. let form=reactive({
  31. type:'phone',
  32. mobile:'',
  33. code:'',
  34. email:''
  35. })
  36. const typeChange=(e)=>{
  37. form.type=e
  38. form.mobile=''
  39. form.code=''
  40. form.email=''
  41. clearTimeout(sendCodeInterval)
  42. isSendCode.value=false
  43. }
  44. //发送验证码
  45. let isSendCode=ref(false)//是否已发送验证码
  46. const handleSendCode=async (type)=>{
  47. if(isSendCode.value) return
  48. let res
  49. if(type=='phone'){
  50. if(!form.mobile){
  51. ElMessage('请输入手机号')
  52. return
  53. }
  54. res=await apiGetSMSCode({
  55. mobile: form.mobile,
  56. area_num: selectArea.value.value
  57. })
  58. }else{
  59. if(!form.email){
  60. ElMessage('请输入邮箱')
  61. return
  62. }
  63. res=await apiGetEmailCode({email: form.email})
  64. }
  65. if(res.code===200){
  66. isSendCode.value=true
  67. ElMessage.success('验证码已发送')
  68. sendCodeInterval=setTimeout(() => {
  69. isSendCode.value=false
  70. }, 60000);
  71. }
  72. }
  73. onUnmounted(()=>{
  74. clearTimeout(sendCodeInterval)
  75. })
  76. const handleLogin=async ()=>{
  77. let params = {}
  78. if (type === 'phone') {
  79. params = {
  80. area_num: selectArea.value.value,
  81. mobile: form.mobile,
  82. verify_code: form.code,
  83. bind_type: 1
  84. }
  85. } else {
  86. params = {
  87. email: form.email,
  88. verify_code: form.code,
  89. bind_type: 2
  90. }
  91. }
  92. if(!params.verify_code){
  93. ElMessage('请填写验证码')
  94. return
  95. }
  96. const res=await apiUserLogin(params)
  97. if(res.code===200){
  98. window.location.href(import.meta.env.VITE_APP_REDIRECT_URI)
  99. }
  100. }
  101. onMounted(()=>{
  102. const redirect_uri=encodeURIComponent(import.meta.env.VITE_APP_REDIRECT_URI)
  103. let obj=new WxLogin({
  104. self_redirect:true,
  105. id:"wx-qrcode-box",
  106. appid: import.meta.env.VITE_APP_APPID,
  107. scope: "snsapi_login",
  108. redirect_uri: redirect_uri,
  109. state: "",
  110. style: "",
  111. href: "",//可传入base64 编码的 css样式
  112. });
  113. })
  114. </script>
  115. <template>
  116. <div class="login-wrap">
  117. <div class="content">
  118. <!-- <img class="close-icon" src="@/assets/icon-close.png" alt=""> -->
  119. <div id="wx-qrcode-box" class="wx-qrcode-box" v-if="$store.state.showLogin"></div>
  120. <div class="bind-accout-box" v-if="$store.state.showBind">
  121. <!-- <img class="logo" :src="$store.state.globalImgUrls.loginTop" alt=""> -->
  122. <!-- 手机号登录 -->
  123. <template v-if="form.type=='phone'">
  124. <h2 class="title">手机号登录</h2>
  125. <div class="phone-area-box" style="margin-bottom: 30px;">
  126. <div class="area-box">
  127. <span style="margin-right: 10px;">国家/区号</span>
  128. <el-dropdown trigger="click" popper-class="self-dropdown">
  129. <span class="el-dropdown-link" style="color: #F3A52F;font-size: 16px;">
  130. {{selectArea.name}}
  131. <el-icon class="el-icon--right">
  132. <arrow-down />
  133. </el-icon>
  134. </span>
  135. <template #dropdown>
  136. <el-dropdown-menu>
  137. <el-dropdown-item
  138. v-for="item in phoneAreaList"
  139. :key="item.value"
  140. @click="selectArea=item"
  141. >{{item.name}}</el-dropdown-item>
  142. </el-dropdown-menu>
  143. </template>
  144. </el-dropdown>
  145. </div>
  146. </div>
  147. <div class="input-item">
  148. <input type="text" v-model="form.mobile" placeholder="请输入手机号">
  149. </div>
  150. <div class="input-item">
  151. <input v-model="form.code" placeholder="请输入验证码" />
  152. <span :class="['send-code-btn',isSendCode&&'send-code-disabled']" @click="handleSendCode('phone')">{{isSendCode?'已发送':'发送验证码'}}</span>
  153. </div>
  154. <div class="global-main-btn login-btn" @click="handleLogin">登录</div>
  155. <div class="bot-img">
  156. <img src="@/assets/icon-login-email.png" alt="" @click="typeChange('email')">
  157. <div>邮箱登录</div>
  158. </div>
  159. </template>
  160. <!-- 邮箱登录 -->
  161. <template v-if="form.type=='email'">
  162. <h2 class="title">邮箱登录</h2>
  163. <div class="input-item">
  164. <input type="text" v-model="form.email" placeholder="请输入手机号">
  165. </div>
  166. <div class="input-item">
  167. <input v-model="form.code" placeholder="请输入验证码" />
  168. <span :class="['send-code-btn',isSendCode&&'send-code-disabled']" @click="handleSendCode('email')">{{isSendCode?'已发送':'发送验证码'}}</span>
  169. </div>
  170. <div class="global-main-btn login-btn" @click="handleLogin">登录</div>
  171. <div class="bot-img">
  172. <img src="@/assets/icon-login-phone.png" alt="" @click="typeChange('phone')">
  173. <div>手机号登录</div>
  174. </div>
  175. </template>
  176. </div>
  177. </div>
  178. </div>
  179. </template>
  180. <style lang="scss">
  181. .login-wrap{
  182. position: fixed;
  183. left: 0;
  184. right: 0;
  185. bottom: 00;
  186. top: 0;
  187. background-color: rgba(0,0,0,0.4);
  188. z-index: 999;
  189. .content{
  190. position: absolute;
  191. top: 50%;
  192. left: 50%;
  193. transform: translate(-50%,-50%);
  194. }
  195. .wx-qrcode-box{
  196. padding-top: 20px;
  197. width: 400px;
  198. max-height: 500px;
  199. background-color: #fff;
  200. border-radius: 16px;
  201. text-align: center;
  202. }
  203. .close-icon{
  204. position: absolute;
  205. top: 10px;
  206. right: 10px;
  207. width: 20px;
  208. height: 20px;
  209. }
  210. .bind-accout-box{
  211. background-color: #fff;
  212. width: 400px;
  213. // min-height: 400px;
  214. padding: 20px;
  215. border-radius: 16px;
  216. .logo{
  217. width: 50px;
  218. display: block;
  219. margin: 0 auto 50px auto;
  220. }
  221. .title{
  222. font-size: 20px;
  223. margin-bottom: 50px;
  224. }
  225. input{
  226. border: none;
  227. outline: none;
  228. }
  229. .input-item{
  230. margin-bottom: 20px;
  231. padding: 8px 0;
  232. border-bottom: 1px solid #F2F2F2;
  233. position: relative;
  234. .send-code-btn{
  235. position: absolute;
  236. right: 0;
  237. bottom: 8px;
  238. color: #F3A52F;
  239. cursor: pointer;
  240. }
  241. .send-code-disabled{
  242. color: #999;
  243. }
  244. }
  245. .login-btn{
  246. width: 300px;
  247. margin: 50px auto;
  248. }
  249. .bot-img{
  250. text-align: center;
  251. font-size: 14px;
  252. img{
  253. width: 50px;
  254. height: 50px;
  255. }
  256. }
  257. }
  258. }
  259. </style>