Login.vue 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348
  1. <template>
  2. <div>
  3. <!--头部-->
  4. <nav class="x-navbar">
  5. <div class="container">
  6. <div class="navbar-header">
  7. <input type="hidden" name="iconUrl" value="">
  8. <a class="navbar-brand" :href="!loginStyle || (loginStyle && (JSON.parse(loginStyle.returnHomeUrl).url)) || ''">
  9. <img :src="loginStyle.logoUrl" alt="">
  10. <span>{{loginStyle.title || ''}}</span>
  11. </a>
  12. </div>
  13. <div class="collapse navbar-collapse navbar-right">
  14. <a :href="loginStyle ? JSON.parse(loginStyle.returnHomeUrl).url : ''">{{loginStyle ? JSON.parse(loginStyle.returnHomeUrl).name : ''}}</a>
  15. <a href="http://uas.ubtob.com/serve#/" v-if="!loginStyle || (loginStyle && (JSON.parse(loginStyle.returnHomeUrl).needHelp))">帮助</a>
  16. </div>
  17. <div class="login-tip">
  18. 为确保您账户的安全及正常使用,依《网络安全法》相关要求,6月1日起会员账户需绑定手机、设置密码保护。感谢您的理解和支持!
  19. </div>
  20. </div>
  21. </nav>
  22. <div class="x-container">
  23. <!-- background slider -->
  24. <div class="x-banner-wrap">
  25. <div class="x-banner">
  26. <ul class="list-unstyled">
  27. <li id="bgStyle" v-bind:style="{ background: `url(${loginStyle.bgUrl}) center center/auto 100% no-repeat ${loginStyle.bgColor}` }">
  28. <a :href="loginStyle.bgLink" v-if="loginStyle.bgLink">
  29. <div class="inner">
  30. <div class="x-title x-text-0"></div>
  31. <div class="x-subtitle x-text-0"></div>
  32. <div class="x-btn-group">
  33. </div>
  34. </div>
  35. </a>
  36. <a v-else style="cursor: default">
  37. <div class="inner">
  38. <div class="x-title x-text-0"></div>
  39. <div class="x-subtitle x-text-0"></div>
  40. <div class="x-btn-group">
  41. </div>
  42. </div>
  43. </a>
  44. </li>
  45. </ul>
  46. </div>
  47. </div>
  48. <div class="x-login-wrap">
  49. <div class="login-tab" v-if="loginWay != 2">
  50. <span @click="loginWay = 0" v-bind:class="{'active': loginWay === 0 }">密码登录</span>
  51. <span @click="loginWay = 3" v-bind:class="{'active': loginWay === 3 }">短信登录</span>
  52. <span @click="ShowWechatCoe(1)" v-bind:class="{'active': loginWay === 1 }" id="weChatBtn">微信登录</span>
  53. </div>
  54. <!--账号密码登录-->
  55. <div class="x-login" v-if="loginWay === 0">
  56. <div id="form-wrap" class="x-login-form">
  57. <el-form :model="login" :rules="rules2" ref="login" class="demo-ruleForm login-form">
  58. <div style="opacity: 0; height: 0; overflow: hidden">
  59. <input type="text" name="hideUserName" id="hideUserName">
  60. <input type="password" name="hidePassword" id="hidePassword">
  61. </div>
  62. <el-form-item prop="username">
  63. <el-input type="text" v-model="login.username" auto-complete="off" placeholder="手机号/邮箱"></el-input>
  64. <i class="fa fa-user"></i>
  65. </el-form-item>
  66. <el-form-item prop="password">
  67. <el-input type="password"
  68. v-model="login.password"
  69. placeholder="密码"
  70. auto-complete="off"
  71. @keyup.enter.native="isLogin(true)"></el-input>
  72. <i class="fa fa-lock"></i>
  73. </el-form-item>
  74. <el-form-item prop="captcha" class="captcha" v-show="showCheckCode">
  75. <el-input type="text"
  76. v-model="login.captcha"
  77. auto-complete="off"
  78. class="code-input"
  79. @keyup.enter.native="isLogin(true)"></el-input>
  80. <img id="captchaImage" class="code-img" src="/sso/login/checkCode"/>
  81. <a class="code-click" @click="getCode">看不清换一张</a>
  82. </el-form-item>
  83. <el-form-item>
  84. <a class="btn login"
  85. @click="isLogin(true)"
  86. :disabled="isLoginDisabled">登录</a>
  87. </el-form-item>
  88. <el-form-item class="text-position">
  89. <div class="page-part" v-if="loginStyle.needRememberPwd">
  90. <el-checkbox v-model="checked">30天免登录</el-checkbox>
  91. </div>
  92. </el-form-item>
  93. </el-form>
  94. <div class="link-go">
  95. <a @click="changeManage" class="first">更换管理员</a>
  96. <span class="line"></span>
  97. <a class="forget" id='forget' @click="goForgetPassword">忘记密码?</a>
  98. <span class="line"></span>
  99. <a id="register" @click="goRegister" class="second">免费注册</a>
  100. </div>
  101. </div>
  102. </div>
  103. <!--短信快捷登录-->
  104. <div class="x-login" v-if="loginWay === 3">
  105. <div id="form-wrap" class="x-login-form">
  106. <el-form :model="fastLogin" :rules="rules3" ref="fastLogin" class="demo-ruleForm login-form loginForm">
  107. <el-form-item prop="mobile">
  108. <el-input type="text" v-model="fastLogin.mobile" auto-complete="off" placeholder="请输入手机号"></el-input>
  109. </el-form-item>
  110. <el-form-item prop="code" class="fastMsg">
  111. <el-input type="text" v-model="fastLogin.code"
  112. auto-complete="off" placeholder="验证码"></el-input>
  113. <el-button type="primary" class="fastCode"
  114. v-show="sendLoginCode"
  115. @click="getCheckCode">获取验证码</el-button>
  116. <el-button type="primary" v-show="!sendLoginCode" class="fastCode code-send">已发送({{login_time}}s)</el-button>
  117. </el-form-item>
  118. <el-form-item>
  119. <a class="btn login"
  120. @click="fastToLogin(true)">登录</a>
  121. </el-form-item>
  122. </el-form>
  123. <div class="link-go">
  124. <a @click="changeManage" class="first">更换管理员</a>
  125. <span class="line"></span>
  126. <a id="register" @click="goRegister" class="second">免费注册</a>
  127. </div>
  128. </div>
  129. </div>
  130. <!--微信扫码登录-->
  131. <div class="x-login scan-login" v-if="loginWay === 1">
  132. <div class="x-login-form">
  133. <div class="scan-body">
  134. <div class="img">
  135. <div id="login_container"></div>
  136. </div>
  137. <div class="content">
  138. <img src="/images/logo/saosao.png" alt="">
  139. <div>
  140. <span>打开 <b>微信</b></span>
  141. <div>扫一扫登录</div>
  142. </div>
  143. </div>
  144. </div>
  145. <div class="link-go" style="padding: 0 18px 12px 0; margin-top: 0;">
  146. <a @click="changeManage" class="first">更换管理员</a>
  147. <span class="line"></span>
  148. <a id="register" @click="goRegister" class="second">免费注册</a>
  149. </div>
  150. </div>
  151. </div>
  152. <!--绑定账号-->
  153. <div class="x-login bind-login" v-if="loginWay === 2">
  154. <div class="x-login-form">
  155. <div class="bind-header">
  156. <span>绑定已有账号</span>
  157. <span @click="loginWay = 0">返回</span>
  158. </div>
  159. <div class="bind-body">
  160. <div class="img"><img :src="wxImg" alt=""/><div>{{wxName}}</div></div>
  161. <div>
  162. <el-form :model="bindAccount" :rules="rules4" ref="bindAccount" class="demo-ruleForm login-form">
  163. <el-form-item prop="username" style="margin: 0 auto 10px !important;">
  164. <el-input type="text"
  165. v-model="bindAccount.username"
  166. auto-complete="off"
  167. placeholder="请输入用户名、手机号或邮箱"></el-input>
  168. </el-form-item>
  169. <el-form-item prop="password" style="margin: 0 auto 10px !important;">
  170. <el-input type="password"
  171. v-model="bindAccount.password"
  172. auto-complete="new-password"
  173. placeholder="密码"
  174. @keyup.enter.native="wxBind"></el-input>
  175. </el-form-item>
  176. <el-form-item style="margin: 0 auto!important;">
  177. <a class="btn login"
  178. @click="wxBind">确定绑定已有账号</a>
  179. </el-form-item>
  180. </el-form>
  181. </div>
  182. <div class="set">还没有优软账号,直接 <a :href="`/register/enterpriseRegistration${this.$store.state.option.fullPath}&tk=${wxToken}`">创建新账号</a></div>
  183. </div>
  184. </div>
  185. </div>
  186. </div>
  187. <!--选择企业弹出框-->
  188. <div>
  189. <el-dialog class="dialog"
  190. :visible.sync="dialogVisible"
  191. size="tiny">
  192. <div class="x-floating x-list" v-show="dialogVisible">
  193. <div class="x-list-header">您要登录的公司是:</div>
  194. <div class="x-list-content">
  195. <ul class="list-unstyled" >
  196. <template v-for="space in this.enterprise">
  197. <li v-text="space.name" @click="chooseOneEnterprise(false, space.id)">华商龙科技有限公司</li>
  198. </template>
  199. </ul>
  200. </div>
  201. </div>
  202. </el-dialog>
  203. </div>
  204. <loading v-show="isShowLoading"/>
  205. </div>
  206. <!--尾部-->
  207. <div v-html="loginStyle.footUrl || ''" class="footer"></div>
  208. </div>
  209. </template>
  210. <script>
  211. import Loading from '~components/common/loading/Loading.vue'
  212. var wxLogin = function () {}
  213. export default {
  214. name: 'login',
  215. components: {
  216. Loading
  217. },
  218. data () {
  219. // 用户名密码登录
  220. var validateUsername = (rule, value, callback) => {
  221. if (value === '') {
  222. this.checkUsername = false
  223. this.showCheckCode = false
  224. } else {
  225. if (this.login.username !== '') {
  226. // 获取密码输错次数
  227. this.$http.get(`/sso/login/getPwdErrorCount`, {params: {username: this.login.username}})
  228. .then(response => {
  229. if (response.data.success) {
  230. this.showCheckCode = false
  231. let getPasswordErrorCount = response.data.content || ''
  232. if (getPasswordErrorCount >= 5) {
  233. this.$message.error('密码错误次数已达上限,今日无法登录')
  234. this.isLoginDisabled = true
  235. this.showCheckCode = false
  236. } else if (getPasswordErrorCount < 3) {
  237. this.isLoginDisabled = false
  238. this.checkUsername = true
  239. this.showCheckCode = false
  240. } else if (getPasswordErrorCount >= 3 && getPasswordErrorCount < 5) {
  241. if (getPasswordErrorCount === 3) {
  242. this.$message.error('当前已输错密码3次,若达到5次今日将无法登录')
  243. }
  244. if (getPasswordErrorCount === 4) {
  245. this.$message.error('当前已输错密码4次,若达到5次今日将无法登录')
  246. }
  247. this.isLoginDisabled = false
  248. this.checkUsername = true
  249. this.showCheckCode = true
  250. } else {
  251. this.checkUsername = false
  252. this.showCheckCode = false
  253. }
  254. } else {
  255. return Promise.reject(response.data)
  256. }
  257. }).catch(err => {
  258. this.isShowLoading = false
  259. this.$message.error(err.errMsg)
  260. })
  261. }
  262. callback()
  263. }
  264. }
  265. var validatePassword = (rule, value, callback) => {
  266. if (value === '') {
  267. this.checkPassword = false
  268. } else {
  269. if (this.login.password !== '') {
  270. this.checkPassword = true
  271. }
  272. callback()
  273. }
  274. }
  275. // 短信便捷登录
  276. var validateMobile = (rule, value, callback) => {
  277. if (value === '') {
  278. this.checkMobile = false
  279. } else {
  280. this.checkMobile = true
  281. callback()
  282. }
  283. }
  284. var validateCode = (rule, value, callback) => {
  285. if (value === '') {
  286. this.checkCode = false
  287. } else {
  288. if (this.fastLogin.code !== '') {
  289. this.checkCode = true
  290. }
  291. callback()
  292. }
  293. }
  294. // 微信扫码登录
  295. var validateWeiUsername = (rule, value, callback) => {
  296. if (value === '') {
  297. this.checkWeiUsername = false
  298. } else {
  299. if (this.bindAccount.username !== '') {
  300. this.checkWeiUsername = true
  301. }
  302. callback()
  303. }
  304. }
  305. var validateWeiPassword = (rule, value, callback) => {
  306. if (value === '') {
  307. this.checkWeiPassword = false
  308. } else {
  309. if (this.bindAccount.password !== '') {
  310. this.checkWeiPassword = true
  311. }
  312. callback()
  313. }
  314. }
  315. return {
  316. login: {
  317. username: '',
  318. password: '',
  319. captcha: '',
  320. spaceUU: ''
  321. },
  322. fastLogin: {
  323. mobile: '',
  324. code: ''
  325. },
  326. bindAccount: {
  327. username: '',
  328. password: ''
  329. },
  330. loginWay: 0,
  331. checked: true,
  332. isShowLoading: false,
  333. checkUsername: false,
  334. checkPassword: false,
  335. showCheckCode: false,
  336. isLoginDisabled: false,
  337. dialogVisible: false,
  338. queryLink: '',
  339. checkMobile: false,
  340. getCodeBtnIsDisabled: true,
  341. sendLoginCode: true,
  342. login_time: 0,
  343. token: '',
  344. checkCode: false,
  345. checkWeiUsername: false,
  346. checkWeiPassword: false,
  347. wxToken: '',
  348. wxImg: '',
  349. wxName: '',
  350. wxUrl: '',
  351. // 用户名密码登录
  352. rules2: {
  353. username: [
  354. {validator: validateUsername, trigger: 'blur'}
  355. ],
  356. password: [
  357. {validator: validatePassword, trigger: 'blur'}
  358. ]
  359. },
  360. // 短信快捷登录
  361. rules3: {
  362. mobile: [
  363. {validator: validateMobile, trigger: 'blur'}
  364. ],
  365. code: [
  366. {validator: validateCode, trigger: 'blur'}
  367. ]
  368. },
  369. // 微信扫码登录
  370. rules4: {
  371. username: [
  372. {validator: validateWeiUsername, trigger: 'blur'}
  373. ],
  374. password: [
  375. {validator: validateWeiPassword, trigger: 'blur'}
  376. ]
  377. }
  378. }
  379. },
  380. mounted () {
  381. this.$nextTick(() => {
  382. this.getUrl()
  383. // if (this.appId === 'mall' || this.appId === 'home') {
  384. // this.getCookie()
  385. // }
  386. this.validUserName()
  387. if (this.$route.query.code) {
  388. this.wxEnterprise()
  389. }
  390. })
  391. },
  392. computed: {
  393. enterprise () {
  394. let chooseEnterprise = this.$store.state.login.chooseRegisterEnterprise.choose.data
  395. return chooseEnterprise
  396. },
  397. loginStyle () {
  398. return this.$store.state.login.loginStyle.data.content ? this.$store.state.login.loginStyle.data.content : ''
  399. }
  400. },
  401. methods: {
  402. ShowWechatCoe () {
  403. wxLogin()
  404. this.loginWay = 1
  405. },
  406. // 获取用户错误次数
  407. validUserName () {
  408. if (this.login.username) {
  409. // 获取密码输错次数
  410. this.$http.get(`/sso/login/getPwdErrorCount`, {params: {username: this.login.username}})
  411. .then(response => {
  412. if (response.data.success) {
  413. let getPasswordErrorCount = response.data.content || ''
  414. if (getPasswordErrorCount >= 5) {
  415. this.$message.error('密码错误次数已达上限,今日无法登录')
  416. this.isLoginDisabled = true
  417. this.showCheckCode = false
  418. } else if (getPasswordErrorCount < 3) {
  419. this.isLoginDisabled = false
  420. this.checkUsername = true
  421. this.showCheckCode = false
  422. } else if (getPasswordErrorCount >= 3 && getPasswordErrorCount < 5) {
  423. if (getPasswordErrorCount === 3) {
  424. this.$message.error('当前已输错密码3次,若达到5次今日将无法登录')
  425. }
  426. if (getPasswordErrorCount === 4) {
  427. this.$message.error('当前已输错密码4次,若达到5次今日将无法登录')
  428. }
  429. this.isLoginDisabled = false
  430. this.checkUsername = true
  431. this.showCheckCode = true
  432. } else {
  433. this.checkUsername = false
  434. this.showCheckCode = false
  435. }
  436. } else {
  437. return Promise.reject(response.data)
  438. }
  439. }).catch(err => {
  440. this.$message.error(err.errMsg)
  441. })
  442. }
  443. },
  444. // 更换管理员
  445. changeManage () {
  446. window.location.href = `appeals/changeManagerAppeal${this.$store.state.option.fullPath}`
  447. },
  448. // 获取url参数
  449. getUrl () {
  450. let wUrl = ''
  451. if (this.$route.query) {
  452. for (var key in this.$route.query) {
  453. if (key !== 'code' && key !== 'state' && key !== 'type') {
  454. wUrl += `${key}=${encodeURIComponent(this.$route.query[key])}&`
  455. }
  456. }
  457. }
  458. if (this.$route.query) {
  459. this.wxUrl = `${window.location.origin}?${wUrl.substr(0, wUrl.length - 1)}`
  460. } else {
  461. this.wxUrl = `${window.location.origin}`
  462. }
  463. var url = window.location.search
  464. var request = {}
  465. if (url.indexOf('?' !== -1)) {
  466. var str = url.substr(1)
  467. var strs = str.split('&')
  468. this.queryLink = str
  469. for (var i = 0; i < strs.length; i++) {
  470. request[strs[i].split('=')[0]] = decodeURI(strs[i].split('=')[1])
  471. }
  472. }
  473. this.appId = request['appId'] || ''
  474. this.returnUrl = request['returnURL'] || ''
  475. this.baseUrl = request['baseUrl'] || ''
  476. },
  477. goForgetPassword () {
  478. let url = `/reset/forgetPasswordValidationAccount?${this.queryLink}`
  479. document.getElementById('forget').href = url
  480. },
  481. // 去注册
  482. goRegister () {
  483. document.getElementById('register').href = `/register/enterpriseRegistration?${this.queryLink}`
  484. },
  485. // 获取验证码
  486. getCode () {
  487. var imgSrc = document.getElementById('captchaImage')
  488. imgSrc.setAttribute('src', '/sso/login/checkCode?timestamp=' + (new Date()).valueOf())
  489. },
  490. // 登录
  491. isLogin (flag) {
  492. this.isShowLoading = true
  493. if (!this.login.username) {
  494. this.isShowLoading = false
  495. this.$message.error('请填写账号')
  496. } else if (!this.login.password) {
  497. this.isShowLoading = false
  498. this.$message.error('请填写密码')
  499. } else {
  500. let param = new FormData()
  501. param.append('username', this.login.username)
  502. param.append('password', this.login.password)
  503. param.append('captcha', this.login.captcha)
  504. param.append('spaceUU', this.login.spaceUU ? this.login.spaceUU : '')
  505. param.append('appId', this.appId ? this.appId : '')
  506. param.append('returnUrl', this.returnUrl ? this.returnUrl : '')
  507. param.append('baseUrl', this.baseUrl ? this.baseUrl : '')
  508. param.append('maxage', this.checked ? 2592000 : '')
  509. let config = {
  510. headers: {'Content-Type': 'multipart/form-data'}
  511. }
  512. this.$http.post('/sso/login', param, config)
  513. .then(response => {
  514. this.isShowLoading = false
  515. if (response.data.success) {
  516. if (response.data.content.spaces) {
  517. // 弹框让用户选择企业
  518. this.$store.commit('login/chooseRegisterEnterprise/GET_ENTERPRISE_SUCCESS', response.data.content.spaces)
  519. this.dialogVisible = flag
  520. } else if (response.data.content.loginUrls) {
  521. // 遍历登录url循环让各应用登录(需要跨域)
  522. let param = response.data.content.data
  523. let a = ''
  524. for (let n in param) {
  525. a += (n + '=' + encodeURIComponent(param[n]) + '&')
  526. }
  527. let params = a.substr(0, a.length - 1)
  528. this.isShowLoading = true
  529. if (response.data.content.currentUrl) {
  530. this.$jsonp(`${response.data.content.currentUrl}?${params}`, {
  531. name: 'successCallback',
  532. timeout: 3000
  533. }, (err, data) => {
  534. if (err) {
  535. this.$message.error('登录超时,请重试')
  536. this.isShowLoading = false
  537. throw err
  538. } else {
  539. this.loginOther(response, params)
  540. }
  541. })
  542. } else {
  543. this.loginOther(response, params, 3000)
  544. }
  545. }
  546. } else {
  547. this.$message.error(response.data)
  548. var count = response.data.errorCount
  549. if (count < 3) {
  550. this.showCheckCode = false
  551. this.isLoginDisabled = false
  552. } else if (count >= 5) {
  553. this.$message.error('密码错误次数已达上限,今日无法登录')
  554. this.isLoginDisabled = true
  555. this.showCheckCode = false
  556. } else if (count >= 3 && count < 5) {
  557. this.getCode()
  558. if (count === 3) {
  559. this.$message.error('当前已输错密码3次,若达到5次今日将无法登录')
  560. }
  561. this.showCheckCode = true
  562. this.isLoginDisabled = false
  563. }
  564. return Promise.reject(response.data)
  565. }
  566. }).catch(err => {
  567. this.isShowLoading = false
  568. let _this = this
  569. setTimeout(function () {
  570. _this.getCode()
  571. }, 100)
  572. this.$message.error(err.errMsg)
  573. })
  574. }
  575. },
  576. // 选择账套
  577. chooseOneEnterprise (flag, spaceUU) {
  578. this.login.spaceUU = spaceUU
  579. this.dialogVisible = false
  580. if (this.$route.query.code) {
  581. this.wxEnterprise(flag)
  582. } else {
  583. if (this.loginWay === 0) {
  584. this.isLogin(flag)
  585. }
  586. if (this.loginWay === 3) {
  587. this.fastToLogin(flag)
  588. }
  589. }
  590. // 记住密码
  591. // if (this.appId === 'mall' || this.appId === 'home') {
  592. // if (this.checked) {
  593. // this.setCookie(this.login.username, this.login.password, 7)
  594. // } else {
  595. // this.clearCookie()
  596. // }
  597. // }
  598. },
  599. // 短信快捷登录
  600. fastToLogin (flag) {
  601. this.isShowLoading = true
  602. if (!this.fastLogin.mobile) {
  603. this.isShowLoading = false
  604. this.$message.error('请填写手机号')
  605. } else {
  606. let param = new FormData()
  607. param.append('mobile', this.fastLogin.mobile)
  608. param.append('code', this.fastLogin.code)
  609. param.append('appId', this.appId)
  610. param.append('token', this.token)
  611. param.append('spaceUU', this.login.spaceUU ? this.login.spaceUU : '')
  612. param.append('returnUrl', this.returnUrl ? this.returnUrl : '')
  613. param.append('baseUrl', this.baseUrl ? this.baseUrl : '')
  614. let config = {
  615. headers: {'Content-Type': 'multipart/form-data'}
  616. }
  617. this.$http.post('/sso/login/sms', param, config)
  618. .then(response => {
  619. this.isShowLoading = false
  620. if (response.data.success) {
  621. if (response.data.content.spaces) {
  622. // 弹框让用户选择企业
  623. this.$store.commit('login/chooseRegisterEnterprise/GET_ENTERPRISE_SUCCESS', response.data.content.spaces)
  624. this.dialogVisible = flag
  625. } else if (response.data.content.loginUrls) {
  626. // 遍历登录url循环让各应用登录(需要跨域)
  627. let param = response.data.content.data
  628. let a = ''
  629. for (let n in param) {
  630. a += (n + '=' + encodeURIComponent(param[n]) + '&')
  631. }
  632. let params = a.substr(0, a.length - 1)
  633. this.isShowLoading = true
  634. if (response.data.content.currentUrl) {
  635. this.$jsonp(`${response.data.content.currentUrl}?${params}`, {
  636. name: 'successCallback',
  637. timeout: 3000
  638. }, (err, data) => {
  639. if (err) {
  640. this.$message.error('登录超时,请重试')
  641. this.isShowLoading = false
  642. throw err
  643. } else {
  644. this.loginOther(response, params)
  645. }
  646. })
  647. } else {
  648. this.loginOther(response, params, 3000)
  649. }
  650. }
  651. } else {
  652. this.$message.error(response.data)
  653. return Promise.reject(response.data)
  654. }
  655. }).catch(err => {
  656. this.isShowLoading = false
  657. let _this = this
  658. setTimeout(function () {
  659. _this.getCode()
  660. }, 100)
  661. this.$message.error(err.errMsg)
  662. })
  663. }
  664. },
  665. getJsonp: function (url, timeout = 500) {
  666. return new Promise((resolve, reject) => {
  667. this.$jsonp(url, {
  668. name: 'successCallback',
  669. timeout: timeout
  670. }, function (err, data) {
  671. if (err) {
  672. reject(err)
  673. throw err
  674. } else {
  675. resolve(data)
  676. }
  677. })
  678. })
  679. },
  680. crossAfter (url) {
  681. try {
  682. window.location.href = url
  683. } catch (err) {
  684. console.log(err)
  685. }
  686. },
  687. loginOther (response, a, timeout) {
  688. const crossAfter = this.crossAfter
  689. let promises = []
  690. for (let i in response.data.content.loginUrls) {
  691. if (response.data.content.currentUrl !== response.data.content.loginUrls[i]) {
  692. promises.push(this.getJsonp(`${response.data.content.loginUrls[i]}?${a}`))
  693. }
  694. }
  695. Promise.all(promises).then(() => {
  696. crossAfter(response.data.content.returnUrl || 'http://www.ubtob.com', timeout)
  697. }).catch(() => {
  698. crossAfter(response.data.content.returnUrl || 'http://www.ubtob.com', timeout)
  699. })
  700. },
  701. // 设置cookie
  702. // setCookie (cName, cPwd, exdays) {
  703. // let exdate = new Date()
  704. // exdate.setTime(exdate.getTime() + 24 * 60 * 60 * 1000 * exdays)
  705. // window.document.cookie = 'userName' + '=' + cName + ';path=/;expires=' + exdate.toGMTString()
  706. // window.document.cookie = 'userPwd' + '=' + cPwd + ';path=/;expires=' + exdate.toGMTString()
  707. // },
  708. // 读取cookies
  709. // getCookie () {
  710. // if (document.cookie.length > 0) {
  711. // let arr = document.cookie.split(';')
  712. // for (var i = 0; i < arr.length; i++) {
  713. // let arr2 = arr[i].split('=')
  714. // if (arr2[0].trim() === 'userName') {
  715. // this.login.username = arr2[1]
  716. // }
  717. // if (arr2[0].trim() === 'userPwd') {
  718. // this.login.password = arr2[1]
  719. // }
  720. // if (this.login.username && this.login.username) {
  721. // this.checked = true
  722. // }
  723. // }
  724. // }
  725. // },
  726. // 清除cookie
  727. // clearCookie () {
  728. // this.setCookie('', '', -1)
  729. // },
  730. // 获取校验码
  731. getCheckCode () {
  732. this.isShowLoading = true
  733. if (!this.fastLogin.mobile) {
  734. this.isShowLoading = false
  735. this.$message.error('请先填写手机号')
  736. } else {
  737. if (this.checkMobile) {
  738. this.$http.get(`/sso/login/sendSmsCode`, {params: {mobile: this.fastLogin.mobile}})
  739. .then(response => {
  740. this.isShowLoading = false
  741. if (response.data) {
  742. if (response.data.success) {
  743. this.token = response.data.content.token
  744. this.$message({
  745. message: '验证码已经发送到您的手机,请注意查收',
  746. type: 'success'
  747. })
  748. this.sendLoginCode = false
  749. this.login_time = 60
  750. var loginTime = setInterval(() => {
  751. this.login_time--
  752. if (this.login_time <= 0) {
  753. this.sendLoginCode = true
  754. clearInterval(loginTime)
  755. }
  756. }, 1000)
  757. } else {
  758. this.$message.error(response.data.errMsg)
  759. }
  760. } else {
  761. return Promise.reject(response.data)
  762. }
  763. }).catch(err => {
  764. this.isShowLoading = false
  765. this.$message.error(err.errMsg)
  766. })
  767. } else {
  768. this.isShowLoading = false
  769. }
  770. }
  771. },
  772. // 微信判断绑定和账套选择
  773. wxEnterprise () {
  774. this.isShowLoading = true
  775. if (this.$route.query.code) {
  776. let param = new FormData()
  777. param.append('code', this.$route.query.code ? this.$route.query.code : '')
  778. param.append('type', 'wx')
  779. param.append('state', this.$route.query.state ? this.$route.query.state : '')
  780. param.append('appId', this.$route.query.appId ? this.$route.query.appId : '')
  781. param.append('returnUrl', this.$route.query.returnURL ? this.$route.query.returnURL : '')
  782. param.append('baseUrl', this.$route.query.baseUrl ? this.$route.query.baseUrl : '')
  783. param.append('spaceUU', this.login.spaceUU ? this.login.spaceUU : '')
  784. let config = {
  785. headers: {'Content-Type': 'multipart/form-data'}
  786. }
  787. this.$http.post('/sso/login/foreignLogin', param, config)
  788. .then(response => {
  789. this.isShowLoading = false
  790. if (response.data.success) {
  791. if (!response.data.content.hasRegister && response.data.content.token) {
  792. this.loginWay = 2
  793. this.wxToken = response.data.content.token
  794. this.$http.get(`/foreign/userInfo/${this.wxToken}`, {params: {token: this.wxToken}})
  795. .then(response => {
  796. if (response.data.success) {
  797. this.wxImg = response.data.content.foreignUserImg
  798. this.wxName = response.data.content.foreignUserName
  799. } else {
  800. return Promise.reject(response.data)
  801. }
  802. }).catch(err => {
  803. this.$message.error(err.errMsg)
  804. })
  805. } else if (response.data.content.spaces) {
  806. // 弹框让用户选择企业
  807. this.$store.commit('login/chooseRegisterEnterprise/GET_ENTERPRISE_SUCCESS', response.data.content.spaces)
  808. this.dialogVisible = true
  809. } else if (response.data.content.loginUrls) {
  810. // 遍历登录url循环让各应用登录(需要跨域)
  811. let param = response.data.content.data
  812. let a = ''
  813. for (let n in param) {
  814. a += (n + '=' + encodeURIComponent(param[n]) + '&')
  815. }
  816. let params = a.substr(0, a.length - 1)
  817. this.isShowLoading = true
  818. if (response.data.content.currentUrl) {
  819. this.$jsonp(`${response.data.content.currentUrl}?${params}`, {
  820. name: 'successCallback',
  821. timeout: 3000
  822. }, (err, data) => {
  823. if (err) {
  824. this.$message.error('登录超时,请重试')
  825. this.isShowLoading = false
  826. throw err
  827. } else {
  828. this.loginOther(response, params)
  829. }
  830. })
  831. } else {
  832. this.loginOther(response, params, 3000)
  833. }
  834. }
  835. } else {
  836. this.$message.error(response.data)
  837. return Promise.reject(response.data)
  838. }
  839. }).catch(err => {
  840. this.isShowLoading = false
  841. let _this = this
  842. setTimeout(function () {
  843. _this.getCode()
  844. }, 100)
  845. this.$message.error(err.errMsg)
  846. })
  847. }
  848. },
  849. // 微信扫码登录
  850. getScan () {
  851. // this.loginWay = 1
  852. this.isShowLoading = true
  853. this.$http.get('/weChat/getQrUrl', {params: {appId: this.$route.query.appId, url: this.wxUrl}})
  854. .then(response => {
  855. this.isShowLoading = false
  856. if (response.data.success) {
  857. window.location.href = response.data.content
  858. } else {
  859. return Promise.reject(response.data)
  860. }
  861. }).catch(err => {
  862. this.isShowLoading = false
  863. this.$message.error(err.errMsg)
  864. })
  865. },
  866. // 绑定企业
  867. wxBind () {
  868. this.isShowLoading = true
  869. if (!this.bindAccount.username) {
  870. this.isShowLoading = false
  871. this.$message.error('请填写账号')
  872. } else if (!this.bindAccount.password) {
  873. this.isShowLoading = false
  874. this.$message.error('请填写密码')
  875. } else {
  876. let param = new FormData()
  877. param.append('_operate', 'account')
  878. param.append('t', this.wxToken)
  879. param.append('username', this.bindAccount.username)
  880. param.append('password', this.bindAccount.password)
  881. let config = {
  882. headers: {'Content-Type': 'multipart/form-data'}
  883. }
  884. this.$http.post('/foreign/addAccount', param, config)
  885. .then(response => {
  886. this.isShowLoading = false
  887. if (response.data.success) {
  888. this.wxEnterprise()
  889. } else {
  890. return Promise.reject(response.data)
  891. }
  892. }).catch(err => {
  893. this.isShowLoading = false
  894. this.$message.error(err.errMsg)
  895. })
  896. }
  897. }
  898. }
  899. }
  900. </script>
  901. <style lang="scss" type="text/scss">
  902. @import '~assets/scss/mixins';
  903. @import '~assets/scss/variables';
  904. .x-navbar{
  905. height: 80px;
  906. line-height: 80px;
  907. margin: 0;
  908. .container{
  909. position: relative;
  910. width: 990px!important;
  911. height: 80px;
  912. .login-tip{
  913. padding: 0 20px;
  914. position: absolute;
  915. top: 57px;
  916. left: 145px;
  917. font-size: 12px;
  918. height: 22px;
  919. line-height: 22px;
  920. color: #999;
  921. background-color: #fef2f2;
  922. border: solid 1px #ffb4a8;
  923. border-radius: 5px;
  924. }
  925. .navbar-header{
  926. height: 80px;
  927. line-height: 80px;
  928. }
  929. a.navbar-brand{
  930. overflow: hidden;
  931. padding: 0px;
  932. height: inherit;
  933. line-height: inherit;
  934. font-family: "\5FAE\8F6F\96C5\9ED1";
  935. font-size: 24px;
  936. font-weight: 400;
  937. color: #888;
  938. img{
  939. margin: 28px 8px 0 0;
  940. max-width: 80px;
  941. max-height: 27px;
  942. vertical-align: middle;
  943. float: left;
  944. }
  945. span{
  946. float: left;
  947. }
  948. }
  949. .collapse{
  950. a{
  951. padding-left: 12px;
  952. margin-right: 10px;
  953. color: #666;
  954. outline: 0;
  955. border-left: 1px solid #ddd;
  956. &:first-child{
  957. border-width: 0;
  958. }
  959. }
  960. }
  961. }
  962. }
  963. .x-container{
  964. position: relative;
  965. height: 475px;
  966. div.link-go {
  967. position: relative;
  968. text-align: right;
  969. margin-top: 55px;
  970. a{
  971. margin-left: 20px;
  972. font-size: 14px;
  973. color: #999;
  974. background: 0 0;
  975. text-decoration: none;
  976. outline: 0;
  977. cursor: pointer;
  978. transition: color .2s ease;
  979. }
  980. a.change{
  981. margin:2px 0 0 50px;
  982. font-size: 12px;
  983. }
  984. span.line {
  985. position: absolute;
  986. top: 1px;
  987. display: inline-block;
  988. margin: 0 10px;
  989. width: 2px;
  990. height: 15px;
  991. background-color: #dddddd;
  992. }
  993. }
  994. /*微信登录*/
  995. .scavenging {
  996. margin-top:22px;
  997. div{
  998. font-size: 12px;
  999. color: #666;
  1000. cursor: pointer;
  1001. img{
  1002. margin-right: 10px;
  1003. }
  1004. }
  1005. }
  1006. /*登录弹出框*/
  1007. .x-floating {
  1008. position: fixed;
  1009. top: 80px;
  1010. left: 50%;
  1011. z-index: 100000;
  1012. opacity: 1;
  1013. -webkit-transition: all .5s;
  1014. -moz-transition: all .5s;
  1015. transition: all .5s;
  1016. }
  1017. .x-list {
  1018. width: 60%;
  1019. height:420px;
  1020. margin-left: -30%;
  1021. background: #fff;
  1022. border-top: 1px solid #e7e7e7;
  1023. cursor: pointer;
  1024. .x-list-header {
  1025. padding: 10px 20px;
  1026. background: #e0e0e0;
  1027. height: 42px;
  1028. line-height: 21px;
  1029. font-size: 14px;
  1030. font-weight: 700;
  1031. color: #505050;
  1032. }
  1033. .x-list-content{
  1034. overflow-y: auto;
  1035. height:375px;
  1036. ul{
  1037. margin-bottom: 0;
  1038. li{
  1039. display:inline-block;
  1040. padding: 10px 20px;
  1041. width: 33%;
  1042. overflow: hidden;
  1043. white-space: nowrap;
  1044. text-overflow: ellipsis;
  1045. height: 42px;
  1046. line-height: 21px;
  1047. font-size: 12px;
  1048. color: #505050;
  1049. border-bottom: 1px solid #e7e7e7;
  1050. &:hover{
  1051. background: #e7e7e7;
  1052. }
  1053. }
  1054. }
  1055. }
  1056. .x-list .x-list-header, .x-list li {
  1057. padding: 10px 20px;
  1058. border-bottom: 1px solid #e7e7e7;
  1059. }
  1060. }
  1061. .x-floating.in {
  1062. top: 80px;
  1063. opacity: 1;
  1064. }
  1065. .x-banner-wrap {
  1066. position: absolute;
  1067. left: 0;
  1068. top: 0;
  1069. width: 100%;
  1070. height: 475px;
  1071. .x-banner {
  1072. position: relative;
  1073. overflow: auto;
  1074. height: 475px;
  1075. text-align: center;
  1076. li{
  1077. width: 100%;
  1078. height: 475px;
  1079. .inner{
  1080. height: 100%;
  1081. }
  1082. }
  1083. }
  1084. }
  1085. .x-login-wrap{
  1086. position: absolute;
  1087. top: 30px;
  1088. right: 50%;
  1089. margin-right: -495px;
  1090. height: 475px;
  1091. z-index: 5;
  1092. .login-tab {
  1093. padding: 0 30px;
  1094. position: relative;
  1095. top: 40px;
  1096. margin: 0 auto;
  1097. width: 346px;
  1098. height: 55px;
  1099. line-height: 55px;
  1100. font-size: 16px;
  1101. color: #999;
  1102. text-align: center;
  1103. background: #fff;
  1104. border-bottom: 1px solid #dcdcdc;
  1105. span{
  1106. margin-right: 42px;
  1107. width: 64px;
  1108. cursor: pointer;
  1109. &:hover, &.active{
  1110. padding-bottom: 15px;
  1111. color: #333;
  1112. border-bottom: 2px solid #282828;
  1113. }
  1114. }
  1115. span:last-child {
  1116. margin-right: 0;
  1117. }
  1118. }
  1119. .x-login {
  1120. position: relative;
  1121. top: 40px;
  1122. width: 346px;
  1123. background: #fff;
  1124. overflow: visible;
  1125. z-index: 4;
  1126. .x-login-form, .x-login-qrcode {
  1127. padding: 20px 20px 10px;
  1128. .btn{
  1129. background: #5078cb;
  1130. color: #fff;
  1131. font-weight: 700;
  1132. letter-spacing: 4px;
  1133. border-radius: 0;
  1134. }
  1135. .x-has-feedback-right {
  1136. float: right;
  1137. display: inline-block;
  1138. a{
  1139. color: #5078cb;
  1140. }
  1141. }
  1142. .x-has-feedback-left {
  1143. position: relative;
  1144. .x-input {
  1145. padding-left: 30px;
  1146. line-height: 18px;
  1147. color: #555;
  1148. border-color: #ccc;
  1149. border-radius: 0;
  1150. box-shadow: none;
  1151. }
  1152. i.fa{
  1153. position: absolute;
  1154. top: 2px;
  1155. left: 0;
  1156. z-index: 2;
  1157. display: block;
  1158. width: 30px;
  1159. height: 34px;
  1160. line-height: 34px;
  1161. text-align: center;
  1162. pointer-events: none;
  1163. color: #999;
  1164. font-size: 18px;
  1165. }
  1166. }
  1167. i.fa-keyboard-o{
  1168. position: absolute;
  1169. right: 10px;
  1170. top: 10px;
  1171. }
  1172. i.fa-arrow-circle-o-right{
  1173. margin-right: 5px;
  1174. font-size: 12px;
  1175. color: #5078cb;
  1176. }
  1177. .warn-text-area{
  1178. margin-top: 5px;
  1179. font-size: 13px;
  1180. color: #000;
  1181. }
  1182. .text-position {
  1183. overflow: hidden;
  1184. .page-part {
  1185. float: left;
  1186. margin-bottom: 0;
  1187. .el-checkbox {
  1188. margin: 0;
  1189. span.el-checkbox__inner{
  1190. width: 14px;
  1191. height: 14px;
  1192. }
  1193. }
  1194. }
  1195. .forget {
  1196. float: right;
  1197. color: #2d8cf0;
  1198. }
  1199. }
  1200. }
  1201. }
  1202. .scan-login {
  1203. .x-login-form{
  1204. padding: 0;
  1205. .scan-header {
  1206. position: relative;
  1207. height: 50px;
  1208. line-height: 50px;
  1209. font-size: 18px;
  1210. font-weight: bold;
  1211. color: #666;
  1212. border: solid 1px #e5e5e5;
  1213. span{
  1214. position: absolute;
  1215. top: -3px;
  1216. padding-left: 10px;
  1217. display: inline-block;
  1218. width: 90px;
  1219. border-bottom: 2px solid #0076ff;
  1220. }
  1221. img{
  1222. position: absolute;
  1223. top: -3px;
  1224. right: -1px;
  1225. height: 50px;
  1226. cursor: pointer;
  1227. }
  1228. }
  1229. .scan-body {
  1230. margin: 0 auto;
  1231. padding: 22px 0 25px;
  1232. text-align: center ;
  1233. div.img{
  1234. position: relative;
  1235. margin: 0 auto;
  1236. width: 180px;
  1237. height: 182px;
  1238. line-height: 182px;
  1239. text-align: center;
  1240. /*border: 1px solid #dcdcdc;*/
  1241. img{
  1242. width: 162px;
  1243. height: 165px;
  1244. }
  1245. }
  1246. #login_container{ position: absolute;left: -60px;top: -12px; z-index: 10;}
  1247. div.content {
  1248. width: 138px;
  1249. margin: 38px auto 0;
  1250. text-align: center;
  1251. overflow: hidden;
  1252. img{
  1253. float: left;
  1254. margin-right: 25px;
  1255. width: 32px;
  1256. height: 27px;
  1257. }
  1258. div{
  1259. float: left;
  1260. width: 80px;
  1261. text-align: left;
  1262. span{
  1263. font-size: 14px;
  1264. color: #999;
  1265. b{
  1266. color: #0076ff;
  1267. }
  1268. }
  1269. div{
  1270. font-size: 14px;
  1271. color: #999;
  1272. }
  1273. }
  1274. }
  1275. }
  1276. }
  1277. }
  1278. .bind-login {
  1279. box-shadow: -2px 1px 6px 0px rgba(0, 0, 0, 0.06);
  1280. border-radius: 6px;
  1281. .x-login-form{
  1282. padding: 0;
  1283. .bind-header {
  1284. overflow: hidden;
  1285. padding: 0 20px;
  1286. height: 50px;
  1287. line-height: 50px;
  1288. font-size: 18px;
  1289. font-weight: bold;
  1290. color: #666;
  1291. border: solid 1px #e5e5e5;
  1292. span {
  1293. &:first-child {
  1294. float: left;
  1295. border-bottom: 2px solid #5078cb;
  1296. }
  1297. &:last-child{
  1298. float: right;
  1299. font-size: 14px;
  1300. color: #5078cb;
  1301. font-weight: normal;
  1302. cursor: pointer;
  1303. }
  1304. }
  1305. }
  1306. .bind-body {
  1307. margin: 22px auto 0;
  1308. padding-bottom: 20px;
  1309. text-align: center ;
  1310. .img{
  1311. margin: 0 auto;
  1312. text-align: center;
  1313. img{
  1314. margin-bottom: 10px;
  1315. width: 60px;
  1316. height: 60px;
  1317. border-radius: 50%;
  1318. }
  1319. div{
  1320. font-size: 14px;
  1321. color: #999;
  1322. }
  1323. }
  1324. .set{
  1325. margin-top: 30px;
  1326. font-size: 12px;
  1327. color: #999;
  1328. a{
  1329. display: inline-block;
  1330. width: 90px;
  1331. line-height: 23px;
  1332. height: 24px;
  1333. text-align: center;
  1334. font-size: 14px;
  1335. color: #5078cb;
  1336. border-radius: 13px;
  1337. border: solid 1px #5078cb;
  1338. }
  1339. }
  1340. }
  1341. }
  1342. }
  1343. }
  1344. }
  1345. .footer{
  1346. padding: 50px 0;
  1347. }
  1348. </style>