loginMobile.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. <template>
  2. <div class="mobile-content"
  3. v-bind:style="{background: `url(${loginStyle.bgUrlMobile}) no-repeat center center`}"
  4. v-bind:class="{'mobile-background-null': !loginStyle.bgUrlMobile}">
  5. <div class="mobile-opacity" v-bind:class="{'mobile-opacity-active': loginStyle.bgUrlMobile}">
  6. <template>
  7. <header-mobile/>
  8. </template>
  9. <div class="login">
  10. <!--<div v-if="loginWay === 0">-->
  11. <div>
  12. <div class="login-way" v-if="activeTab === 0">
  13. <div class="page-part">
  14. <mt-field auto-complete="off" placeholder="手机号/邮箱" v-model="login.username" @blur.native.capture="codeCount"></mt-field>
  15. </div>
  16. <div class="page-part">
  17. <mt-field placeholder="密码" v-model="login.password" type="password"></mt-field>
  18. <template>
  19. <div class="handle">
  20. <span class="fast-login" @click="activeTab = 1">短信快捷登录</span>
  21. <span class="pwd" @click="forgetPwd">忘记密码?</span>
  22. </div>
  23. </template>
  24. </div>
  25. <template v-if="showCheckCode">
  26. <div class="page-part">
  27. <mt-field placeholder="验证码" v-model="login.captcha">
  28. <img :src="imgSrc" height="45px" width="100px" @click="getCode">
  29. </mt-field>
  30. </div>
  31. </template>
  32. <div class="page-part">
  33. <mt-button size="large" type="primary" @click="checkLogin(true)">登录</mt-button>
  34. </div>
  35. </div>
  36. <div class="login-way" v-if="activeTab === 1">
  37. <div class="page-part">
  38. <mt-field auto-complete="off"
  39. placeholder="请输入手机号"
  40. v-model="fastLogin.mobile"
  41. :state="state.mobile"></mt-field>
  42. </div>
  43. <div class="page-part">
  44. <mt-field auto-complete="off"
  45. placeholder="短信验证码"
  46. v-model="fastLogin.code">
  47. <span class="token" @click="getCheckCode" v-text="tokenText">获取验证码</span>
  48. </mt-field>
  49. <template>
  50. <div class="handle">
  51. <span class="pwd" @click="activeTab = 0">用户名密码登录</span>
  52. </div>
  53. </template>
  54. </div>
  55. <div class="page-part">
  56. <mt-button size="large" type="primary" @click="fastToLogin(true)">登录</mt-button>
  57. </div>
  58. </div>
  59. <div class="login-btn">
  60. <p>还没有优软云账号?</p>
  61. <mt-button size="large" plain type="primary" @click="jump">立即注册</mt-button>
  62. </div>
  63. </div>
  64. <!--<div v-if="loginWay === 1">-->
  65. <!--<div class="user-info">-->
  66. <!--<div class="img"><img :src="bhImg || '/images/all/icon_mall_index.png'" alt=""></div>-->
  67. <!--<div class="user-name">{{bhName}}</div>-->
  68. <!--</div>-->
  69. <!--<div class="page-part">-->
  70. <!--<mt-field auto-complete="off" placeholder="请输入账号" v-model="bhLogin.username"></mt-field>-->
  71. <!--</div>-->
  72. <!--<div class="page-part">-->
  73. <!--<mt-field placeholder="请输入密码" v-model="bhLogin.password" type="password"></mt-field>-->
  74. <!--</div>-->
  75. <!--<div class="page-part">-->
  76. <!--<mt-button size="large" type="primary" @click="bhBind">确&nbsp;&nbsp;&nbsp;定</mt-button>-->
  77. <!--</div>-->
  78. <!--<div class="login-btn">-->
  79. <!--<p>还没有优软云账号?</p>-->
  80. <!--<mt-button size="large" plain type="primary"><a :href="`/register/enterpriseRegistration${this.$store.state.option.fullPath}&tk=${bhToken}`" class="go">创建新账号</a></mt-button>-->
  81. <!--</div>-->
  82. <!--</div>-->
  83. <mt-popup v-model="popupVisible" position="right" class="mint-popup" :modal="false">
  84. <ul style="height:100vh;overflow-y:auto">
  85. <li class="listitem itemgreen">选择您要登录的公司:</li>
  86. <li v-for="item in enterprise" class="listitem" @click="selectEnterprise(false, item.id)">{{ item.name }}</li>
  87. </ul>
  88. </mt-popup>
  89. </div>
  90. </div>
  91. </div>
  92. </template>
  93. <script>
  94. // function getCodeD (appId) {
  95. // let paramse = {
  96. // appId: appId
  97. // }
  98. // return new Promise((resolve, reject) => {
  99. // if (window.cordova) {
  100. // window.MrJsBridge.call((returnValue) => {
  101. // resolve(returnValue)
  102. // }, (error) => {
  103. // console.log(error)
  104. // reject(error)
  105. // }, 'getCode', paramse)
  106. // }
  107. // })
  108. // }
  109. import HeaderMobile from '~components/mobile/HeaderMobile.vue'
  110. export default {
  111. name: 'loginMobile',
  112. components: {
  113. HeaderMobile
  114. },
  115. data () {
  116. return {
  117. loading: false,
  118. popupVisible: false,
  119. imgSrc: '',
  120. showCheckCode: false,
  121. login: {
  122. username: '',
  123. password: '',
  124. spaceUU: '',
  125. captcha: ''
  126. },
  127. // bhLogin: {
  128. // username: '',
  129. // password: ''
  130. // },
  131. fastLogin: {
  132. mobile: '',
  133. code: ''
  134. },
  135. state: {
  136. mobile: 'error'
  137. },
  138. appId: '',
  139. returnUrl: '',
  140. baseUrl: '',
  141. bhCode: '',
  142. bhToken: '',
  143. bhImg: '',
  144. bhName: '',
  145. tokenCode: '',
  146. tokenTime: 60,
  147. tokenText: '获取验证码',
  148. // loginWay: 0,
  149. activeTab: 0
  150. }
  151. },
  152. mounted () {
  153. this.$nextTick(() => {
  154. this.getUrl()
  155. // 碧合应用授权认证
  156. // window.document.addEventListener('deviceready', function () {
  157. // window.addEventListener('js_bridge_called', function () {
  158. // })
  159. // })
  160. // let appId = 'a9f624cbbdb947049f5638880b0ecbb2'
  161. // getCodeD(appId).then((data) => {
  162. // // 成功回调 code
  163. // alert(data)
  164. // this.bhCode = data
  165. // this.bhToLogin()
  166. // }).catch((error) => {
  167. // console.log(error)
  168. // })
  169. })
  170. },
  171. computed: {
  172. enterprise () {
  173. return this.$store.state.login.chooseRegisterEnterprise.choose.data
  174. },
  175. loginStyle () {
  176. return this.$store.state.login.loginStyle.data.content ? this.$store.state.login.loginStyle.data.content : ''
  177. }
  178. },
  179. methods: {
  180. selectEnterprise (flag, type) {
  181. this.login.spaceUU = type
  182. this.popupVisible = flag
  183. // if (this.$route.query.type) {
  184. // this.bhToLogin()
  185. // } else {
  186. // if (this.activeTab === 0) {
  187. // this.toLogin(flag)
  188. // }
  189. // if (this.activeTab === 1) {
  190. // this.fastToLogin(flag)
  191. // }
  192. // }
  193. if (this.activeTab === 0) {
  194. this.toLogin(flag)
  195. }
  196. if (this.activeTab === 1) {
  197. this.fastToLogin(flag)
  198. }
  199. },
  200. // 弹窗处理
  201. downToast (type) {
  202. this.$toast({
  203. message: type,
  204. iconClass: 'el-icon-warning'
  205. })
  206. },
  207. // 忘记密码
  208. forgetPwd () {
  209. window.location.href = `/reset/forgetPasswordValidationAccount${this.$store.state.option.fullPath}`
  210. },
  211. jump () {
  212. window.location.href = `/register/enterpriseRegistration${this.$store.state.option.fullPath}`
  213. },
  214. getUrl () {
  215. this.appId = this.$store.state.option.appId
  216. this.returnUrl = this.$store.state.option.returnUrl
  217. this.baseUrl = this.$store.state.option.baseUrl
  218. },
  219. getCode () {
  220. this.imgSrc = '/sso/login/checkCode?timestamp=' + (new Date()).valueOf()
  221. },
  222. checkLogin (flag) {
  223. if (!this.login.username) {
  224. this.$toast({message: '请填写账号', iconClass: 'el-icon-warning'})
  225. } else if (!this.login.password) {
  226. this.$toast({message: '请填写密码', iconClass: 'el-icon-warning'})
  227. } else {
  228. this.toLogin(flag)
  229. }
  230. },
  231. codeCount () {
  232. this.$http.get(`/sso/login/getPwdErrorCount`, {params: {username: this.login.username}})
  233. .then(response => {
  234. if (response.data.success) {
  235. let count = response.data.content || ''
  236. if (count >= 3 && count < 5) {
  237. this.showCheckCode = true
  238. this.getCode()
  239. this.$toast({
  240. message: '当前已输错密码' + count + '次,若达到5次今日将无法登陆',
  241. iconClass: 'el-icon-warning'
  242. })
  243. } else if (count === 5) {
  244. this.$toast({
  245. message: '密码错误次数已达上限,今日无法登陆',
  246. iconClass: 'el-icon-warning'
  247. })
  248. }
  249. } else {
  250. this.$toast({
  251. message: response.data.errMsg,
  252. iconClass: 'el-icon-warning'
  253. })
  254. }
  255. }).catch(err => {
  256. this.$toast({
  257. message: err.errMsg,
  258. iconClass: 'el-icon-warning'
  259. })
  260. })
  261. },
  262. toLogin (flag) {
  263. this.$indicator.open('登录中...')
  264. let param = new FormData()
  265. param.append('username', this.login.username)
  266. param.append('password', this.login.password)
  267. param.append('captcha', this.login.captcha)
  268. param.append('appId', this.appId)
  269. param.append('returnUrl', this.returnUrl)
  270. param.append('baseUrl', this.baseUrl)
  271. param.append('spaceUU', this.login.spaceUU)
  272. let config = {
  273. headers: {'Content-Type': 'multipart/form-data'}
  274. }
  275. this.$http.post('/sso/login', param, config)
  276. .then(response => {
  277. this.$indicator.close()
  278. if (response.data.success) {
  279. // 弹框用户选择企业
  280. if (response.data.content.spaces) {
  281. this.$store.commit('login/chooseRegisterEnterprise/GET_ENTERPRISE_SUCCESS', response.data.content.spaces)
  282. this.popupVisible = flag
  283. } else if (response.data.content.loginUrls) {
  284. // 遍历登录url循环让各个应用登录
  285. let param = response.data.content.data
  286. let a = ''
  287. for (let n in param) {
  288. a += (n + '=' + encodeURIComponent(param[n]) + '&')
  289. }
  290. let params = a.substr(0, a.length - 1)
  291. this.$indicator.open('跳转中...')
  292. if (response.data.content.currentUrl) {
  293. this.$jsonp(`${response.data.content.currentUrl}?${params}`, {
  294. name: 'successCallback',
  295. timeout: 5000
  296. }, (err, data) => {
  297. if (err) {
  298. this.$indicator.close()
  299. this.$toast({
  300. message: '登录超时,请重试',
  301. iconClass: 'el-icon-error'
  302. })
  303. this.login.spaceUU = ''
  304. throw err
  305. } else {
  306. this.loginOther(response, params)
  307. }
  308. })
  309. } else {
  310. this.loginOther(response, params, 3000)
  311. }
  312. }
  313. } else {
  314. this.login.password = ''
  315. this.$toast({
  316. message: response.data.errMsg,
  317. iconClass: 'el-icon-error'
  318. })
  319. let count = response.data.errorCount
  320. if (count >= 3 && count < 5) {
  321. this.showCheckCode = true
  322. this.getCode()
  323. let _this = this
  324. setTimeout(function () {
  325. _this.getCode()
  326. }, 100)
  327. this.$toast({
  328. message: '当前已输错密码' + count + '次,若达到5次今日将无法登陆',
  329. iconClass: 'el-icon-warning'
  330. })
  331. }
  332. }
  333. }).catch(err => {
  334. this.$toast({
  335. message: err.errMsg,
  336. iconClass: 'el-icon-error'
  337. })
  338. })
  339. },
  340. getJsonp: function (url, timeout = 500) {
  341. return new Promise((resolve, reject) => {
  342. this.$jsonp(url, {
  343. name: 'successCallback',
  344. timeout: timeout
  345. }, function (err, data) {
  346. if (err) {
  347. reject(err)
  348. throw err
  349. } else {
  350. resolve(data)
  351. }
  352. })
  353. })
  354. },
  355. crossAfter (url) {
  356. try {
  357. window.location.href = url
  358. } catch (err) {
  359. console.log(err)
  360. }
  361. },
  362. loginOther (response, a, timeout) {
  363. const crossAfter = this.crossAfter
  364. let promises = []
  365. for (let i in response.data.content.loginUrls) {
  366. if (response.data.content.currentUrl !== response.data.content.loginUrls[i]) {
  367. promises.push(this.getJsonp(`${response.data.content.loginUrls[i]}?${a}`))
  368. }
  369. }
  370. Promise.all(promises).then(() => {
  371. crossAfter(response.data.content.returnUrl || 'http://www.ubtob.com', timeout)
  372. }).catch(() => {
  373. crossAfter(response.data.content.returnUrl || 'http://www.ubtob.com', timeout)
  374. })
  375. },
  376. // 碧合绑定账号
  377. // bhBind () {
  378. // this.$indicator.open('绑定中请稍后...')
  379. // if (!this.bhLogin.username) {
  380. // this.$indicator.close()
  381. // this.downToast('请填写账号')
  382. // } else if (!this.bhLogin.password) {
  383. // this.$indicator.close()
  384. // this.downToast('请填写密码')
  385. // } else {
  386. // let param = new FormData()
  387. // param.append('_operate', 'account')
  388. // param.append('t', this.bhToken)
  389. // param.append('username', this.bhLogin.username)
  390. // param.append('password', this.bhLogin.password)
  391. // let config = {
  392. // headers: {'Content-Type': 'multipart/form-data'}
  393. // }
  394. // this.$http.post('/foreign/addAccount', param, config)
  395. // .then(response => {
  396. // this.$indicator.close()
  397. // if (response.data.success) {
  398. // this.bhToLogin()
  399. // } else {
  400. // return Promise.reject(response.data)
  401. // }
  402. // }).catch(err => {
  403. // this.$indicator.close()
  404. // this.$toast({
  405. // message: err.errMsg,
  406. // iconClass: 'el-icon-error'
  407. // })
  408. // })
  409. // }
  410. // },
  411. // 判断是否绑定、选择账套
  412. // bhToLogin () {
  413. // this.$indicator.open('加载中...')
  414. // if (this.$route.query.type) {
  415. // let param = new FormData()
  416. // param.append('code', this.bhCode || '')
  417. // param.append('type', 'bh')
  418. // param.append('appId', this.$route.query.appId ? this.$route.query.appId : '')
  419. // param.append('returnUrl', this.$route.query.returnURL ? this.$route.query.returnURL : '')
  420. // param.append('baseUrl', this.$route.query.baseUrl ? this.$route.query.baseUrl : '')
  421. // param.append('spaceUU', this.login.spaceUU ? this.login.spaceUU : '')
  422. // let config = {
  423. // headers: {'Content-Type': 'multipart/form-data'}
  424. // }
  425. // this.$http.post('/sso/login/foreignLogin', param, config)
  426. // .then(response => {
  427. // this.$indicator.close()
  428. // if (response.data.success) {
  429. // if (!response.data.content.hasRegister && response.data.content.token) {
  430. // this.loginWay = 1
  431. // this.bhToken = response.data.content.token
  432. // this.$http.get(`/foreign/userInfo/${this.bhToken}`, {params: {token: this.bhToken}})
  433. // .then(response => {
  434. // if (response.data.success) {
  435. // this.bhImg = response.data.content.foreignUserImg
  436. // this.bhName = response.data.content.foreignUserName
  437. // } else {
  438. // return Promise.reject(response.data)
  439. // }
  440. // }).catch(err => {
  441. // this.$toast({
  442. // message: err.errMsg,
  443. // iconClass: 'el-icon-error'
  444. // })
  445. // })
  446. // } else if (response.data.content.spaces) {
  447. // // 弹框让用户选择企业
  448. // this.$store.commit('login/chooseRegisterEnterprise/GET_ENTERPRISE_SUCCESS', response.data.content.spaces)
  449. // this.popupVisible = true
  450. // this.$indicator.open('跳转中...')
  451. // } else if (response.data.content.loginUrls) {
  452. // // 遍历登录url循环让各应用登录(需要跨域)
  453. // let param = response.data.content.data
  454. // let a = ''
  455. // for (let n in param) {
  456. // a += (n + '=' + encodeURIComponent(param[n]) + '&')
  457. // }
  458. // let params = a.substr(0, a.length - 1)
  459. // this.$indicator.open('加载中...')
  460. // if (response.data.content.currentUrl) {
  461. // this.$jsonp(`${response.data.content.currentUrl}?${params}`, {
  462. // name: 'successCallback',
  463. // timeout: 3000
  464. // }, (err, data) => {
  465. // if (err) {
  466. // this.$toast({
  467. // message: '登录超时,请重试',
  468. // iconClass: 'el-icon-error'
  469. // })
  470. // this.$indicator.close()
  471. // throw err
  472. // } else {
  473. // this.loginOther(response, params)
  474. // }
  475. // })
  476. // } else {
  477. // this.loginOther(response, params, 3000)
  478. // }
  479. // }
  480. // } else {
  481. // this.$toast({
  482. // message: response.data,
  483. // iconClass: 'el-icon-error'
  484. // })
  485. // }
  486. // }).catch(err => {
  487. // this.$indicator.close()
  488. // let _this = this
  489. // setTimeout(function () {
  490. // _this.getCode()
  491. // }, 100)
  492. // this.$toast({
  493. // message: err.errMsg,
  494. // iconClass: 'el-icon-error'
  495. // })
  496. // })
  497. // }
  498. // },
  499. // 验证手机号
  500. validateMobile () {
  501. let reg = /^1[0-9]{10}$/
  502. if (!this.fastLogin.mobile) {
  503. this.downToast('请先填写手机号')
  504. this.state.mobile = 'error'
  505. } else {
  506. if (!reg.test(this.fastLogin.mobile)) {
  507. this.downToast('请填写正确的手机号')
  508. this.state.mobile = 'warning'
  509. } else {
  510. this.state.mobile = 'success'
  511. }
  512. }
  513. },
  514. // 短信获取验证码
  515. getCheckCode () {
  516. if (this.tokenTime > 0 && this.tokenTime < 60) {
  517. this.downToast('请稍后再点击,我在倒计时')
  518. } else {
  519. this.validateMobile()
  520. if (this.state.mobile === 'success') {
  521. this.$indicator.open('获取中...')
  522. let _this = this
  523. this.$http.get('/sso/login/sendSmsCode', {params: {mobile: this.fastLogin.mobile}})
  524. .then(response => {
  525. this.$indicator.close()
  526. if (response.data.success) {
  527. this.tokenCode = response.data.content.token
  528. this.$toast({
  529. message: '验证码已经发送到您的手机,请注意查收',
  530. iconClass: 'el-icon-success'
  531. })
  532. this.tokenText = '已发送(' + this.tokenTime + 'S)'
  533. let setTime = setInterval(() => {
  534. _this.tokenTime--
  535. this.tokenText = '已发送(' + this.tokenTime + 'S)'
  536. if (this.tokenTime <= 0) {
  537. clearInterval(setTime)
  538. _this.tokenText = '获取验证码'
  539. _this.tokenTime = 60
  540. }
  541. }, 1000)
  542. } else {
  543. this.state.mobile = 'error'
  544. this.downToast(response.data.errMsg)
  545. }
  546. }).catch((err) => {
  547. this.$indicator.close()
  548. this.downToast(err.errMsg)
  549. })
  550. }
  551. }
  552. },
  553. // 短信快捷登录
  554. fastToLogin (flag) {
  555. if (this.fastLogin.mobile === '') {
  556. this.downToast('手机号不能为空')
  557. } else if (this.fastLogin.code === '') {
  558. this.downToast('验证码不能为空')
  559. } else {
  560. this.$indicator.open('登录中...')
  561. let param = new FormData()
  562. param.append('mobile', this.fastLogin.mobile)
  563. param.append('code', this.fastLogin.code)
  564. param.append('appId', this.$route.query.appId ? this.$route.query.appId : '')
  565. param.append('token', this.tokenCode)
  566. param.append('spaceUU', this.login.spaceUU ? this.login.spaceUU : '')
  567. param.append('returnUrl', this.returnUrl ? this.returnUrl : '')
  568. param.append('baseUrl', this.baseUrl ? this.baseUrl : '')
  569. let config = {
  570. headers: {'Content-Type': 'multipart/form-data'}
  571. }
  572. this.$http.post('/sso/login/sms', param, config)
  573. .then(response => {
  574. this.$indicator.close()
  575. if (response.data.success) {
  576. // 弹框用户选择企业
  577. if (response.data.content.spaces) {
  578. this.$store.commit('login/chooseRegisterEnterprise/GET_ENTERPRISE_SUCCESS', response.data.content.spaces)
  579. this.popupVisible = flag
  580. } else if (response.data.content.loginUrls) {
  581. // 遍历登录url循环让各个应用登录
  582. let param = response.data.content.data
  583. let a = ''
  584. for (let n in param) {
  585. a += (n + '=' + encodeURIComponent(param[n]) + '&')
  586. }
  587. let params = a.substr(0, a.length - 1)
  588. this.$indicator.open('跳转中...')
  589. if (response.data.content.currentUrl) {
  590. this.$jsonp(`${response.data.content.currentUrl}?${params}`, {
  591. name: 'successCallback',
  592. timeout: 5000
  593. }, (err, data) => {
  594. if (err) {
  595. this.$indicator.close()
  596. this.$toast({
  597. message: '登录超时,请重试',
  598. iconClass: 'el-icon-error'
  599. })
  600. this.login.spaceUU = ''
  601. throw err
  602. } else {
  603. this.loginOther(response, params)
  604. }
  605. })
  606. } else {
  607. this.loginOther(response, params, 3000)
  608. }
  609. }
  610. } else {
  611. this.login.password = ''
  612. this.$toast({
  613. message: response.data.errMsg,
  614. iconClass: 'el-icon-error'
  615. })
  616. let count = response.data.errorCount
  617. if (count >= 3 && count < 5) {
  618. this.showCheckCode = true
  619. this.getCode()
  620. let _this = this
  621. setTimeout(function () {
  622. _this.getCode()
  623. }, 100)
  624. this.$toast({
  625. message: '当前已输错密码' + count + '次,若达到5次今日将无法登陆',
  626. iconClass: 'el-icon-warning'
  627. })
  628. }
  629. }
  630. }).catch(err => {
  631. this.$toast({
  632. message: err.errMsg,
  633. iconClass: 'el-icon-error'
  634. })
  635. })
  636. }
  637. }
  638. }
  639. }
  640. </script>