index.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. <template>
  2. <div class="f-main">
  3. <div class="content-top">
  4. <p>企业注册</p>
  5. <a class="go" @click="goRegister"><i class="fa fa-long-arrow-right"></i>个人注册</a>
  6. </div>
  7. <template v-if="step === 1">
  8. <div class="f-form">
  9. <div class="page-part">
  10. <mt-field placeholder="手机号码"
  11. v-model="step1.mobile"
  12. :state="state.mobile"
  13. type="tel"
  14. ></mt-field>
  15. </div>
  16. <div class="page-part">
  17. <mt-field placeholder="验证码" v-model="code">
  18. <img :src="imgSrc" height="45px" width="100px" @click="getCode">
  19. </mt-field>
  20. </div>
  21. <div class="page-part">
  22. <mt-field auto-complete="off"
  23. placeholder="短信验证码"
  24. v-model="step1.token"
  25. :state="state.token">
  26. <span class="token" @click="getCheckCode" v-text="tokenText">获取验证码</span>
  27. </mt-field>
  28. </div>
  29. </div>
  30. <div class="form-btn">
  31. <div class="page-part">
  32. <el-checkbox v-model="checked">我已阅读并同意 <a href="/common/agreement" class="rgba">《优软云服务条款》</a></el-checkbox>
  33. </div>
  34. <mt-button type="primary" size="large" @click.native="checkPhone">验证手机</mt-button>
  35. </div>
  36. </template>
  37. <template v-if="step === 2">
  38. <div class="f-form">
  39. <div class="page-part">
  40. <mt-field placeholder="企业名称"
  41. :attr="{ maxlength: 20 }"
  42. v-model="step2.spaceName"
  43. :state="state.spaceName"></mt-field>
  44. </div>
  45. <div class="page-part">
  46. <mt-field placeholder="营业执照号"
  47. v-model="step2.businessCode"
  48. :state="state.businessCode"></mt-field>
  49. </div>
  50. <div class="page-part" v-if="!hasRegister">
  51. <mt-field placeholder="管理员姓名"
  52. v-model="step2.vipName"
  53. :state="state.vipName"></mt-field>
  54. </div>
  55. <div class="page-part" v-if="!hasRegister">
  56. <mt-field placeholder="登录密码"
  57. :attr="{ maxlength: 20 }"
  58. v-model="step2.password"
  59. :state="state.password"
  60. type="password"
  61. auto-complete="new-password"
  62. @input.native="validatePassword"></mt-field>
  63. <template v-if="step2.password">
  64. <p class="pwd">密码强度 <em :class="{sm:progress === '弱', md: progress === '中', ld:progress === '强'}"></em> <em :class="{md: progress === '中', ld:progress === '强'}"></em> <em :class="{ld:progress === '强'}"></em> <span :class="{smstep:progress === '弱', mdstep: progress === '中', ldstep:progress === '强'}" v-text="progress">强</span></p>
  65. <p class="pwd">密码须为8-20字符的英文、数字混合</p>
  66. </template>
  67. </div>
  68. <div class="page-part" v-if="hasRegister">
  69. <mt-field placeholder="登录密码"
  70. v-model="step2.password"
  71. :state="state.password"
  72. type="password"
  73. auto-complete="new-password"></mt-field>
  74. <template v-if="!step2.password">
  75. <p class="pwd" style="text-align:right;"><a href="/reset/forgetPasswordValidationAccount">忘记密码?</a></p>
  76. </template>
  77. <template v-if="step2.password">
  78. <p class="pwd">手机号已注册,请输入原密码</p>
  79. </template>
  80. </div>
  81. <div class="page-part" v-if="!hasRegister">
  82. <mt-field placeholder="密码确认"
  83. v-model="step2.confirm"
  84. :state="state.confirm"
  85. type="password"
  86. auto-complete="new-password"></mt-field>
  87. </div>
  88. <div class="page-part" v-if="!hasEmail">
  89. <mt-field placeholder="联系邮箱"
  90. v-model="step2.email"
  91. :state="state.email"
  92. type="email"></mt-field>
  93. </div>
  94. </div>
  95. <div class="form-btn">
  96. <mt-button type="primary" size="large" @click.native="sureRegister">完成注册</mt-button>
  97. </div>
  98. </template>
  99. </div>
  100. </template>
  101. <script>
  102. export default {
  103. name: 'registerEnterprise',
  104. data () {
  105. return {
  106. code: '',
  107. imgSrc: '',
  108. step: 1,
  109. state: {
  110. mobile: 'error',
  111. token: 'error',
  112. spaceName: 'error',
  113. businessCode: 'error',
  114. vipName: 'error',
  115. password: 'error',
  116. confirm: 'error',
  117. email: null
  118. },
  119. step1: {
  120. mobile: '',
  121. token: ''
  122. },
  123. step2: {
  124. spaceName: '',
  125. businessCode: '',
  126. vipName: '',
  127. password: '',
  128. confirm: '',
  129. email: ''
  130. },
  131. checked: true,
  132. tokenCode: '',
  133. tokenTime: 60,
  134. tokenText: '获取验证码',
  135. hasRegister: false,
  136. hasEmail: false,
  137. progress: '弱'
  138. }
  139. },
  140. mounted () {
  141. this.$nextTick(() => {
  142. this.getCode()
  143. })
  144. },
  145. watch: {
  146. 'step1.token': {
  147. handler (newVal) {
  148. if (newVal.length === 6) {
  149. this.validateCode()
  150. }
  151. },
  152. immediate: true
  153. }
  154. },
  155. methods: {
  156. getCode () {
  157. this.imgSrc = '/sso/resetPwd/checkCaptcha?timestamp=' + (new Date()).valueOf()
  158. },
  159. // 注册
  160. goRegister () {
  161. window.location.href = `/register/personalRegistration${this.$store.state.option.fullPath}`
  162. },
  163. // 弹窗处理
  164. downToast (type) {
  165. this.$toast({
  166. message: type,
  167. iconClass: 'el-icon-warning'
  168. })
  169. },
  170. // 验证手机号
  171. validateMobile () {
  172. let reg = /^1[0-9]{10}$/
  173. if (!this.step1.mobile) {
  174. this.downToast('请先填写手机号')
  175. this.state.mobile = 'error'
  176. } else {
  177. if (!reg.test(this.step1.mobile)) {
  178. this.downToast('请填写正确的手机号')
  179. this.state.mobile = 'warning'
  180. } else {
  181. this.state.mobile = 'success'
  182. }
  183. }
  184. },
  185. // 验证正确的验证码
  186. validateCode () {
  187. if (!this.step1.token) {
  188. this.downToast('请先填写验证码')
  189. this.state.token = 'error'
  190. } else {
  191. if (!this.step1.mobile) {
  192. this.downToast('请先填写正确的手机号码')
  193. this.state.token = 'warning'
  194. } else {
  195. if (this.tokenCode) {
  196. let param = new FormData()
  197. param.append('mobile', this.step1.mobile)
  198. param.append('token', this.tokenCode)
  199. param.append('code', this.step1.token)
  200. let config = {
  201. headers: {'Content-Type': 'multipart/form-data'}
  202. }
  203. this.$http.post('/sso/personal/register/checkCode', param, config)
  204. .then(response => {
  205. if (response.data.success) {
  206. this.state.token = 'success'
  207. } else {
  208. this.$toast({
  209. message: response.data.errMsg,
  210. iconClass: 'el-icon-error'
  211. })
  212. }
  213. }).catch((err) => {
  214. this.downToast(err.errMsg)
  215. })
  216. } else {
  217. this.downToast('请点击先获取验证码信息')
  218. this.state.token = 'warning'
  219. }
  220. }
  221. }
  222. },
  223. // 获取验证码
  224. getCheckCode () {
  225. if (this.tokenTime > 0 && this.tokenTime < 60) {
  226. this.downToast('请稍后再点击,我在倒计时')
  227. } else if (this.code === '') {
  228. this.downToast('请输入验证码后获取!')
  229. } else {
  230. this.validateMobile()
  231. if (this.state.mobile === 'success') {
  232. this.$indicator.open('获取中...')
  233. let _this = this
  234. this.$http.get('/sso/personal/register/checkCode', {params: {mobile: this.step1.mobile, timestamp: new Date().getTime() + '', code: this.code}})
  235. .then(response => {
  236. this.$indicator.close()
  237. if (response.data.errMsg) {
  238. this.$toast({
  239. message: response.data.errMsg,
  240. iconClass: 'el-icon-error'
  241. })
  242. this.code = ''
  243. this.getCode()
  244. return
  245. }
  246. if (response.data) {
  247. this.tokenCode = response.data.token
  248. this.$toast({
  249. message: '验证码已经发送到您的手机,请注意查收',
  250. iconClass: 'el-icon-success'
  251. })
  252. this.tokenText = '已发送(' + this.tokenTime + 'S)'
  253. let setTime = setInterval(() => {
  254. _this.tokenTime--
  255. this.tokenText = '已发送(' + this.tokenTime + 'S)'
  256. if (this.tokenTime <= 0) {
  257. clearInterval(setTime)
  258. _this.tokenText = '获取验证码'
  259. _this.tokenTime = 60
  260. }
  261. }, 1000)
  262. }
  263. }).catch(() => {
  264. this.$indicator.close()
  265. this.downToast('获取失败,请检查网络')
  266. })
  267. }
  268. }
  269. },
  270. // 验证手机
  271. checkPhone () {
  272. if (this.state.mobile !== 'success') {
  273. this.validateMobile()
  274. } else if (this.state.token !== 'success') {
  275. this.validateCode()
  276. } else if (this.checked === false) {
  277. this.downToast('您对阅读条款未做勾选')
  278. } else {
  279. this.$indicator.open('验证手机中...')
  280. let param = new FormData()
  281. param.append('mobile', this.step1.mobile)
  282. param.append('code', this.step1.token)
  283. param.append('appId', this.$store.state.option.appId)
  284. param.append('token', this.tokenCode)
  285. let config = {
  286. headers: {'Content-Type': 'multipart/form-data'}
  287. }
  288. this.$http.post('/sso/userspace/register/checkAdminTel', param, config)
  289. .then(response => {
  290. this.$indicator.close()
  291. if (response.data.success) {
  292. response.data.content.hasEmail ? this.hasEmail = true : this.hasEmail = false
  293. response.data.content.hasRegister ? this.hasRegister = true : this.hasRegister = false
  294. this.step = 2
  295. }
  296. }).catch((err) => {
  297. this.$indicator.close()
  298. this.downToast(err.errMsg)
  299. })
  300. }
  301. },
  302. // 验证企业名
  303. validateSpaceName () {
  304. if (!this.step2.spaceName) {
  305. this.downToast('请填写企业名称')
  306. this.state.spaceName = 'error'
  307. } else {
  308. if (this.step2.spaceName.length > 20) {
  309. this.downToast('输入长度过长,限定20个字符以内')
  310. this.state.spaceName = 'warning'
  311. } else {
  312. this.$http.get(`/api/userspace/checkSpaceName`, {params: {spaceName: this.step2.spaceName}})
  313. .then(response => {
  314. if (response.data.success) {
  315. this.state.spaceName = 'success'
  316. } else {
  317. this.state.spaceName = 'warning'
  318. this.downToast(response.data.errMsg)
  319. }
  320. })
  321. }
  322. }
  323. },
  324. // 验证营业号
  325. validateBusinessCode () {
  326. let reg = /^[A-Za-z0-9]+$/
  327. if (!this.step2.businessCode) {
  328. this.downToast('请填写营业执照号')
  329. this.state.businessCode = 'error'
  330. } else {
  331. if (!reg.test(this.step2.businessCode)) {
  332. this.downToast('请填写正确的营业执照号')
  333. this.state.businessCode = 'warning'
  334. } else {
  335. this.$http.get(`/api/userspace/checkBusinessCode`, {params: {businessCode: this.step2.businessCode}})
  336. .then(response => {
  337. if (response.data.success) {
  338. this.state.businessCode = 'success'
  339. } else {
  340. this.state.businessCode = 'warning'
  341. this.downToast(response.data.errMsg)
  342. }
  343. })
  344. }
  345. }
  346. },
  347. // 验证管理员名
  348. validateVipName () {
  349. if (!this.step2.vipName) {
  350. this.downToast('请填写管理员姓名')
  351. this.state.vipName = 'error'
  352. } else {
  353. if (this.step2.vipName.length > 20) {
  354. this.downToast('输入长度请限制在20个字符以内')
  355. this.state.vipName = 'warning'
  356. } else {
  357. this.state.vipName = 'success'
  358. }
  359. }
  360. },
  361. // 验证密码强度
  362. validatePassword () {
  363. let reg1 = /^(?=.{8,20})(((?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]))|((?=.*[0-9])((?=.*[a-zA-Z]))(?=.*[^a-zA-Z0-9]))).*$/
  364. let reg2 = /^(?=.{8,20})(((?=.*[0-9])(?=.*[a-z]))|((?=.*[0-9])(?=.*[A-Z]))).*$/
  365. if (reg1.test(this.step2.password)) {
  366. this.progress = '强'
  367. } else if (reg2.test(this.step2.password)) {
  368. this.progress = '中'
  369. } else {
  370. this.progress = '弱'
  371. }
  372. },
  373. // 验证密码
  374. validatePasswordTip () {
  375. let reg2 = /^(?=.{8,20})(((?=.*[0-9])(?=.*[a-z]))|((?=.*[0-9])(?=.*[A-Z]))).*$/
  376. if (!this.step2.password) {
  377. this.downToast('请输入密码')
  378. this.state.password = 'error'
  379. } else {
  380. if (!reg2.test(this.step2.password)) {
  381. this.downToast('密码须为8-20字符的英文、数字混合')
  382. this.state.password = 'warning'
  383. } else {
  384. this.state.password = 'success'
  385. if (this.step2.confirm) {
  386. this.validateConfirm()
  387. }
  388. }
  389. }
  390. },
  391. // 验证密码
  392. validatePasswordTipHas () {
  393. if (!this.step2.password) {
  394. this.downToast('请输入密码')
  395. this.state.password = 'error'
  396. } else {
  397. this.state.password = 'success'
  398. }
  399. },
  400. // 验证二次密码
  401. validateConfirm () {
  402. if (!this.step2.confirm) {
  403. this.downToast('请再次输入密码')
  404. this.state.confirm = 'error'
  405. } else {
  406. if (this.step2.confirm === this.step2.password) {
  407. this.state.confirm = 'success'
  408. } else {
  409. this.state.confirm = 'warning'
  410. this.downToast('两次输入密码不一致,请重新输入')
  411. }
  412. }
  413. },
  414. // 验证邮箱
  415. validateEmail () {
  416. let reg = /^([\w-])+(\.\w+)*@([\w-])+((\.\w{2,3}){1,3})$/
  417. if (this.step2.email) {
  418. if (!reg.test(this.step2.email)) {
  419. this.downToast('请输入正确的邮箱地址格式')
  420. this.state.email = 'warning'
  421. } else {
  422. this.$http.get('/api/user/checkEmail', {params: {email: this.step2.email}})
  423. .then(response => {
  424. if (response.data.hasRegister) {
  425. this.state.email = 'warning'
  426. this.downToast('该邮箱已被注册')
  427. } else {
  428. this.state.email = 'success'
  429. }
  430. }).catch((err) => {
  431. this.downToast(err.errMsg)
  432. })
  433. }
  434. } else {
  435. // this.downToast('请填写联系邮箱信息')
  436. this.state.email = 'success'
  437. }
  438. },
  439. // 注册请求方法
  440. sbmitRegister () {
  441. this.$indicator.open('注册中...')
  442. let param = new FormData()
  443. param.append('spaceName', this.step2.spaceName)
  444. param.append('businessCode', this.step2.businessCode)
  445. param.append('vipName', this.step2.vipName || '')
  446. param.append('password', this.step2.password)
  447. param.append('email', this.step2.email || '')
  448. param.append('appId', this.$store.state.option.appId)
  449. param.append('inviteSpaceUU', this.$store.state.option.inviteSpaceUU)
  450. param.append('inviteUserUU', this.$store.state.option.inviteUserUU)
  451. param.append('invitationTime', this.$store.state.option.invitationTime)
  452. param.append('t', this.$route.query.tk ? this.$route.query.tk : '')
  453. param.append('returnUrl', this.$route.query.returnURL ? this.$route.query.returnURL : '')
  454. let config = {
  455. headers: {'Content-Type': 'multipart/form-data'}
  456. }
  457. this.$http.post('/sso/userspace/register', param, config)
  458. .then(response => {
  459. this.$indicator.close()
  460. if (response.data.success) {
  461. if (response.data.content) {
  462. let param = response.data.content.data
  463. let a = ''
  464. for (let n in param) {
  465. a += (n + '=' + encodeURIComponent(param[n]) + '&')
  466. }
  467. let params = a.substr(0, a.length - 1)
  468. this.isShowLoading = true
  469. if (response.data.content.currentUrl) {
  470. this.$jsonp(`${response.data.content.currentUrl}?${params}`, {
  471. name: 'successCallback',
  472. timeout: 3000
  473. }, (err, data) => {
  474. if (err) {
  475. this.$message.error('注册成功,请点击下方“立即登录”完成登录')
  476. this.isShowLoading = false
  477. throw err
  478. } else {
  479. this.loginOther(response, params)
  480. }
  481. })
  482. } else {
  483. this.loginOther(response, params, 3000)
  484. }
  485. } else {
  486. window.location.href = '/overRegister/overEnterprise'
  487. }
  488. } else {
  489. this.downToast(response.data.errMsg)
  490. }
  491. }).catch((err) => {
  492. this.$indicator.close()
  493. this.downToast(err.errMsg)
  494. })
  495. },
  496. // 企业注册
  497. sureRegister () {
  498. if (!this.hasRegister) {
  499. if (this.state.spaceName !== 'success') {
  500. this.validateSpaceName()
  501. } else if (this.state.businessCode !== 'success') {
  502. this.validateBusinessCode()
  503. } else if (this.state.vipName !== 'success') {
  504. this.validateVipName()
  505. } else if (this.state.password !== 'success') {
  506. this.validatePasswordTip()
  507. } else if (this.state.confirm !== 'success') {
  508. this.validateConfirm()
  509. } else if (this.state.email !== 'success') {
  510. this.validateEmail()
  511. } else {
  512. this.sbmitRegister()
  513. }
  514. } else {
  515. if (!this.hasEmail) {
  516. if (this.state.spaceName !== 'success') {
  517. this.validateSpaceName()
  518. } else if (this.state.businessCode !== 'success') {
  519. this.validateBusinessCode()
  520. } else if (this.state.password !== 'success') {
  521. this.validatePasswordTip()
  522. } else if (this.state.email !== 'success') {
  523. this.validateEmail()
  524. } else {
  525. this.sbmitRegister()
  526. }
  527. } else {
  528. if (this.state.spaceName !== 'success') {
  529. this.validateSpaceName()
  530. } else if (this.state.businessCode !== 'success') {
  531. this.validateBusinessCode()
  532. } else if (this.state.password !== 'success') {
  533. this.validatePasswordTipHas()
  534. } else {
  535. this.sbmitRegister()
  536. }
  537. }
  538. }
  539. },
  540. getJsonp: function (url, timeout = 500) {
  541. return new Promise((resolve, reject) => {
  542. this.$jsonp(url, {
  543. name: 'successCallback',
  544. timeout: timeout
  545. }, function (err, data) {
  546. if (err) {
  547. reject(err)
  548. throw err
  549. } else {
  550. resolve(data)
  551. }
  552. })
  553. })
  554. },
  555. crossAfter (url) {
  556. try {
  557. window.location.href = url
  558. } catch (err) {
  559. console.log(err)
  560. }
  561. },
  562. loginOther (response, a, timeout) {
  563. const crossAfter = this.crossAfter
  564. let promises = []
  565. for (let i in response.data.content.loginUrls) {
  566. if (response.data.content.currentUrl !== response.data.content.loginUrls[i]) {
  567. promises.push(this.getJsonp(`${response.data.content.loginUrls[i]}?${a}`))
  568. }
  569. }
  570. let returnUrl = decodeURIComponent(this.$route.query.returnURL)
  571. Promise.all(promises).then(() => {
  572. crossAfter(returnUrl || 'http://www.ubtob.com', timeout)
  573. }).catch(() => {
  574. crossAfter(returnUrl || 'http://www.ubtob.com', timeout)
  575. })
  576. }
  577. }
  578. }
  579. </script>