loginMobile.vue 23 KB

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