login.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <template>
  2. <view class="login-page">
  3. <image :src="globalImgUrls.loginTop" class="top-img" mode="aspectFill"></image>
  4. <view class="form-wrap tel-wrap" v-if="active==='手机号'">
  5. <van-field
  6. :value="tel"
  7. placeholder="请输入手机号"
  8. :border="false"
  9. center
  10. type="number"
  11. title-width="60px"
  12. @change="inputChange('tel', $event)"
  13. >
  14. <template slot="label">
  15. <picker
  16. mode="selector"
  17. :range="telAreaList"
  18. range-key="name"
  19. :value="telAreaIndex"
  20. @change="telAreaChange"
  21. header-text="请选择您的国际区号"
  22. >
  23. <view>
  24. +{{ telAreaList[telAreaIndex].value}}
  25. <van-icon name="arrow-down" style="margin-left: 4px"/>
  26. </view>
  27. </picker>
  28. </template>
  29. <button slot="button" class="tel-btn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">获取微信手机号</button>
  30. </van-field>
  31. <van-field
  32. :value="verifyCode"
  33. placeholder="请输入4位验证码"
  34. :border="false"
  35. title-width="60px"
  36. type="number"
  37. maxlength='4'
  38. center
  39. @change="inputChange('verifyCode', $event)"
  40. >
  41. <text slot="button" class="sendcode-btn" v-if="!isSendVerifyCode" @click="handleSendVerifyCode('tel')">发送验证码</text>
  42. <van-count-down slot="button" :time="countDownTime" format="ss S" @finish="timeFinished" v-else/>
  43. </van-field>
  44. <view class="global-btn-yellow-change submit-btn" @click="handleSubmit('tel')">提交</view>
  45. </view>
  46. <view class="form-wrap email-wrap" v-else>
  47. <van-field
  48. :value="email"
  49. placeholder="请输入邮箱地址"
  50. :border="false"
  51. center
  52. title-width="60px"
  53. @change="inputChange('email',$event)"
  54. />
  55. <van-field
  56. :value="verifyCode"
  57. placeholder="请输入4位验证码"
  58. :border="false"
  59. title-width="60px"
  60. center
  61. type="number"
  62. maxlength='4'
  63. @change="inputChange('verifyCode',$event)"
  64. >
  65. <text slot="button" class="sendcode-btn" type="primary" v-if="!isSendVerifyCode" @click="handleSendVerifyCode('email')">发送验证码</text>
  66. <van-count-down slot="button" :time="countDownTime" format="ss S" @finish="timeFinished" v-else/>
  67. </van-field>
  68. <view class="global-btn-yellow-change submit-btn" @click="handleSubmit('email')">提交</view>
  69. </view>
  70. <!-- 底部 -->
  71. <view class="change-wrap">
  72. <view class="text">{{active==='手机号'?'使用邮箱登录':'使用手机号登录'}}</view>
  73. <image class="img" @click="handleChange" mode="aspectFill" :src="active==='手机号'?'../static/login-email.png':'../static/login-phone.png'"></image>
  74. </view>
  75. <view class="bot-text">专注为全球投资者提供中立客观的研究服务</view>
  76. </view>
  77. </template>
  78. <script>
  79. import { apiGetSMSCode, apiGetEmailCode,apiGetWechatPhone } from '@/api/common'
  80. import { apiUserLogin } from '@/api/user'
  81. import { telVerify, emailVerify } from '@/utils/common'
  82. export default {
  83. data() {
  84. return {
  85. active: "手机号",
  86. telAreaList: [
  87. {
  88. name: "大陆+86",
  89. value: "86",
  90. },
  91. {
  92. name: "香港+852",
  93. value: "852",
  94. },
  95. {
  96. name: "台湾+886",
  97. value: "886",
  98. },
  99. {
  100. name: "美国+1",
  101. value: "1",
  102. },
  103. {
  104. name: "新加坡+65",
  105. value: "65",
  106. },
  107. ], //手机号区号
  108. telAreaIndex: 0, //选择手机号区号第几个
  109. tel: "",//手机号
  110. email: "",//邮箱
  111. verifyCode: "",//验证码
  112. isSendVerifyCode: false,//是否已经发送验证码
  113. countDownTime: 60 * 1000,//倒计时60秒
  114. };
  115. },
  116. onShow(){
  117. uni.hideHomeButton({
  118. fail(res){
  119. console.log(res);
  120. }
  121. })
  122. },
  123. methods: {
  124. // 获取微信绑定的手机号登录
  125. async getPhoneNumber({detail}){
  126. const res=await apiGetWechatPhone({
  127. encryptedData:detail.encryptedData||'',
  128. iv:detail.iv||'',
  129. code:detail.code||'',
  130. isBind:true,
  131. })
  132. if(res.code===200){
  133. uni.switchTab({
  134. url: '/pages/report/report'
  135. })
  136. this.$store.dispatch('getUserInfo')
  137. this.$store.dispatch('getTabBar')
  138. }else if(res.code===400){
  139. this.$store.commit('setToken', '')
  140. this.$store.dispatch('getUserInfo')
  141. }
  142. },
  143. handleChange(){
  144. if(this.active==='手机号'){
  145. this.active='邮箱'
  146. }else{
  147. this.active='手机号'
  148. }
  149. },
  150. // 区号改变
  151. telAreaChange(e) {
  152. this.telAreaIndex = e.detail.value;
  153. },
  154. //倒计时结束
  155. timeFinished() {
  156. this.isSendVerifyCode = false
  157. },
  158. inputChange(key, event) {
  159. this[key] = event.detail
  160. },
  161. //发送验证码
  162. async handleSendVerifyCode(type) {
  163. let res
  164. if (type === 'tel') {
  165. if (!this.tel) {
  166. uni.showToast({
  167. title: "请输入手机号",
  168. icon: "none"
  169. })
  170. return
  171. }
  172. res = await apiGetSMSCode({
  173. mobile: this.tel,
  174. area_num: this.telAreaList[this.telAreaIndex].value
  175. })
  176. } else {
  177. if (!this.email) {
  178. uni.showToast({
  179. title: "请输入邮箱地址",
  180. icon: "none"
  181. })
  182. return
  183. }
  184. res = await apiGetEmailCode({
  185. email: this.email
  186. })
  187. }
  188. if (res.code === 200) {
  189. this.isSendVerifyCode = true
  190. uni.showToast({
  191. title: "验证码已发送",
  192. icon: "success"
  193. })
  194. }
  195. },
  196. // 提交
  197. async handleSubmit(type) {
  198. let params = {}
  199. if (type === 'tel') {
  200. params = {
  201. area_num: Number(this.telAreaList[this.telAreaIndex].value),
  202. mobile: this.tel,
  203. verify_code: this.verifyCode,
  204. bind_type: 1
  205. }
  206. } else {
  207. params = {
  208. email: this.email,
  209. verify_code: this.verifyCode,
  210. bind_type: 2
  211. }
  212. }
  213. if (!params.verify_code) {
  214. uni.showToast({
  215. title: "请输入验证码",
  216. icon: "none"
  217. })
  218. return
  219. }
  220. const res = await apiUserLogin(params)
  221. if (res.code === 200) {
  222. uni.switchTab({
  223. url: '/pages/report/report'
  224. })
  225. this.$store.dispatch('getUserInfo')
  226. this.$store.dispatch('getTabBar')
  227. }
  228. }
  229. },
  230. };
  231. </script>
  232. <style lang="scss">
  233. .login-page {
  234. padding: 34rpx;
  235. text-align: center;
  236. @media screen and (min-width: 700px){
  237. max-width: 500px;
  238. margin-left: auto;
  239. margin-right: auto;
  240. }
  241. }
  242. .top-img {
  243. width: 140rpx;
  244. height: 140rpx;
  245. margin-top: 70rpx;
  246. margin-bottom: 100rpx;
  247. @media screen and (min-width: 700px){
  248. width: 70px;
  249. height: 70px;
  250. margin-top: 35px;
  251. margin-bottom: 50px;
  252. }
  253. }
  254. .van-cell {
  255. border-bottom: 1px solid $global-border-color;
  256. }
  257. .sendcode-btn{
  258. color:$global-text-color-main;
  259. }
  260. .tel-btn{
  261. font-size: 14px;
  262. color: $global-text-color-main;
  263. background: transparent;
  264. line-height: 1;
  265. padding: 0;
  266. }
  267. .tel-btn::after{
  268. border: none;
  269. }
  270. .change-wrap{
  271. margin-top: 100rpx;
  272. @media screen and (min-width: 700px){
  273. margin-top: 50px;
  274. }
  275. .text{
  276. color: #CFCFCF;
  277. display: flex;
  278. align-items: center;
  279. justify-content: center;
  280. &::before{
  281. content: '';
  282. width: 140rpx;
  283. height: 1rpx;
  284. display: inline-block;
  285. background-color: #E1E2E6;
  286. margin-right: 20rpx;
  287. @media screen and (min-width: 700px){
  288. width: 70px;
  289. margin-right: 10px;
  290. }
  291. }
  292. &::after{
  293. content: '';
  294. width: 140rpx;
  295. height: 1rpx;
  296. display: inline-block;
  297. background-color: #E1E2E6;
  298. margin-left: 20rpx;
  299. @media screen and (min-width: 700px){
  300. width: 70px;
  301. margin-left: 10px;
  302. }
  303. }
  304. }
  305. .img{
  306. margin-top: 40rpx;
  307. width: 80rpx;
  308. height: 80rpx;
  309. @media screen and (min-width: 700px){
  310. margin-top: 20px;
  311. width: 40px;
  312. height: 40px;
  313. }
  314. }
  315. }
  316. .submit-btn {
  317. width: 490rpx;
  318. margin-left: auto;
  319. margin-right: auto;
  320. margin-top: 100rpx;
  321. @media screen and (min-width: 700px){
  322. width: 245px;
  323. margin-top: 50px;
  324. line-height: 35px;
  325. }
  326. }
  327. .bot-text{
  328. position: fixed;
  329. left: 50%;
  330. transform: translateX(-50%);
  331. bottom: 100rpx;
  332. color: $global-text-color-999;
  333. width: 100%;
  334. @media screen and (min-width: 700px){
  335. bottom: 50px;
  336. }
  337. }
  338. </style>