login.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. <template>
  2. <div class="website-login-box">
  3. <div class="login-box">
  4. <div class="close-icon-box">
  5. <i class="el-icon-circle-close close-icon" @click="close"></i>
  6. </div>
  7. <div class="login-form">
  8. <div class="login-tab" :class="{
  9. active1:nowTab.id === 1,
  10. active2:nowTab.id === 2
  11. }">
  12. <div class="tab-item" :class="{
  13. active:nowTab.id === tab.id
  14. }" v-for="(tab, index) in tabs" :key="index" @click="nowTab = tab">
  15. {{ tab.name }}
  16. </div>
  17. </div>
  18. <el-form :model="loginForm" :rules="loginRules" status-icon ref="loginForm" label-position="left">
  19. <el-form-item prop="phone">
  20. <el-input type="text" prefix-icon="iconfont huifont-shoujihao" v-model="loginForm.phone"
  21. placeholder="手机号" maxlength="11">
  22. </el-input>
  23. </el-form-item>
  24. <el-form-item prop="code" class="image-item" v-if="nowTab.id === 1">
  25. <el-input type="text" prefix-icon="iconfont huifont-tuxingyanzhengma" v-model="loginForm.code"
  26. placeholder="图片验证码" maxlength="4"></el-input>
  27. <div class="code-image" @click="imgCodeFunc">
  28. <img v-if="codeImg" :src="codeImg" alt="图片验证码" />
  29. <p class="color-blue">看不清?点击刷新</p>
  30. </div>
  31. </el-form-item>
  32. <el-form-item prop="phoneCode" class="phone-code" v-if="nowTab.id === 1">
  33. <el-input type="number" prefix-icon="iconfont huifont-duanxinyanzhengma"
  34. v-model="loginForm.phoneCode" placeholder="短信验证码"
  35. oninput="if(value.length > 6) value=value.slice(0, 6)">
  36. </el-input>
  37. <div class="get-code-btn">
  38. <el-button type="primary" size="samll" @click="getPhoneCode"
  39. :disabled="codeName !== '获取验证码'">
  40. {{codeName}}
  41. </el-button>
  42. </div>
  43. </el-form-item>
  44. <el-form-item prop="password" v-if="nowTab.id === 2">
  45. <el-input type="password" prefix-icon="iconfont huifont-mima" v-model="loginForm.password"
  46. :show-password="true" placeholder="请输入密码">
  47. </el-input>
  48. </el-form-item>
  49. </el-form>
  50. <el-button class="submit" type="primary" @click="loginSubmit" :loading="loginLoading">登录</el-button>
  51. </div>
  52. </div>
  53. </div>
  54. </template>
  55. <script>
  56. import {
  57. login,
  58. getImgCode,
  59. sendPhoneCode,
  60. getUserInfo,
  61. selectOrangaized
  62. } from '@/api/loginRegister';
  63. import {
  64. setToken,
  65. setComment
  66. } from '@/uitls/auth';
  67. export default {
  68. data() {
  69. return {
  70. loginForm: {
  71. phone: '',
  72. code: '',
  73. phoneCode: '',
  74. password: ''
  75. },
  76. loginLoading: false,
  77. codeImg: '',
  78. codeName: '获取验证码', //获取验证码text
  79. isDisabled: false, //获取验证码按钮状态
  80. loginRules: {
  81. code: [{
  82. required: true,
  83. message: '请输入图片验证码',
  84. trigger: 'blur'
  85. }],
  86. phone: [{
  87. required: true,
  88. message: '请输入手机号',
  89. trigger: 'blur'
  90. }, {
  91. validator: (rule, value, callback) => {
  92. if (!/^1[123456789]\d{9}$/.test(value)) {
  93. callback(new Error("请输入正确的手机号"));
  94. } else {
  95. callback();
  96. }
  97. },
  98. trigger: 'blur'
  99. }],
  100. phoneCode: [{
  101. required: true,
  102. message: '请输入短信验证码',
  103. trigger: 'blur'
  104. }]
  105. },
  106. tabs: [{
  107. id: 1,
  108. name: '验证码登录'
  109. }, {
  110. id: 2,
  111. name: '账号密码登录'
  112. }],
  113. nowTab: {
  114. id: 1,
  115. name: '验证码登录'
  116. }
  117. };
  118. },
  119. mounted() {
  120. this.imgCodeFunc();
  121. if (this.$store.getters.codeNumber != 60) this.codeReset();
  122. },
  123. methods: {
  124. imgCodeFunc() {
  125. getImgCode().then(res => {
  126. if (res.state) {
  127. this.codeImg = res.data.pngBase64;
  128. }
  129. })
  130. },
  131. getPhoneCode() {
  132. if (this.isDisabled) return;
  133. this.$refs.loginForm.validateField('phone', valid => {
  134. if (!valid) {
  135. this.$refs.loginForm.validateField('code', valid => {
  136. if (!valid) {
  137. sendPhoneCode(this.loginForm.phone, this.loginForm.code).then(res => {
  138. if (res.state) {
  139. this.codeReset();
  140. this.$message.success('发送成功');
  141. }
  142. })
  143. }
  144. })
  145. }
  146. })
  147. },
  148. codeReset() {
  149. //重置获取验证码倒计时
  150. let codeNumber = this.$store.getters.codeNumber;
  151. codeNumber--;
  152. this.handleCode(codeNumber);
  153. let codeRestFn = setInterval(() => {
  154. codeNumber--;
  155. this.handleCode(codeNumber);
  156. if (codeNumber == 0) clearInterval(codeRestFn); //停止
  157. }, 1000);
  158. },
  159. handleCode(codeNumber) {
  160. //code操作
  161. this.codeName = codeNumber == 0 ? '获取验证码' : '重新获取' + codeNumber;
  162. this.isDisabled = codeNumber == 0 ? false : true;
  163. this.$store.dispatch('app/changeCodeNumber', codeNumber == 0 ? 60 : codeNumber);
  164. },
  165. close() {
  166. if (this.loginLoading) return;
  167. this.$emit('callback');
  168. },
  169. loginSubmit() {
  170. if (this.loginLoading) return;
  171. this.loginLoading = true;
  172. this.$refs['loginForm'].validate(valid => {
  173. if (!valid) return this.loginLoading = false;
  174. this.loginFunc();
  175. })
  176. },
  177. loginFunc() {
  178. let postData = this.nowTab.id === 1 ? {
  179. phone: this.loginForm.phone,
  180. phoneCode: this.loginForm.phoneCode
  181. } : {
  182. phone: this.loginForm.phone,
  183. password: this.loginForm.password
  184. };
  185. login(postData).then(res => {
  186. if (res.state) {
  187. setToken(res.data.token);
  188. getUserInfo().then(res => {
  189. if (res.state) {
  190. let user = res.data;
  191. let organization = user.organizationList.find(node => node.contactTel ===
  192. user.phone);
  193. if (!organization) organization = user.organizationList[0];
  194. this.$store.dispatch('app/changeOrganization', organization);
  195. this.$store.dispatch('app/changeUser', user);
  196. this.$store.dispatch('app/changeMenuData', user.workarkResource ? JSON
  197. .parse(user.workarkResource) : []);
  198. setComment(user.workarkMenu ? user.workarkMenu : JSON.stringify([]));
  199. this.$chat.connect();
  200. setTimeout(() => {
  201. this.successLogin();
  202. }, 500)
  203. } else {
  204. this.loginLoading = false;
  205. }
  206. })
  207. } else {
  208. this.loginLoading = false;
  209. }
  210. })
  211. },
  212. successLogin() {
  213. this.loginLoading = false;
  214. this.$emit('callback', 'init')
  215. this.$message.success('登录成功');
  216. }
  217. }
  218. };
  219. </script>
  220. <style lang="scss" scoped>
  221. .login-tab {
  222. display: flex;
  223. border: 1px solid #bebebe;
  224. margin-bottom: 28px;
  225. height: 36px;
  226. border-radius: 4px;
  227. align-items: center;
  228. position: relative;
  229. &:before {
  230. content: '';
  231. position: absolute;
  232. background: #bebebe;
  233. width: 159px;
  234. height: 28px;
  235. border-radius: 4px;
  236. z-index: 8;
  237. transition: left 0.3s;
  238. }
  239. &.active1:before {
  240. left: 4px;
  241. }
  242. &.active2:before {
  243. left: 167px;
  244. }
  245. }
  246. .tab-item {
  247. flex: 1;
  248. text-align: center;
  249. z-index: 9;
  250. cursor: pointer;
  251. transition: color 0.3s;
  252. &.active {
  253. color: #fff;
  254. }
  255. }
  256. .website-login-box {
  257. width: 100%;
  258. height: 100%;
  259. display: flex;
  260. align-items: center;
  261. justify-content: center;
  262. }
  263. .close-icon {
  264. font-size: 30px;
  265. color: #c9cdd3;
  266. cursor: pointer;
  267. }
  268. .close-icon-box {
  269. padding: 10px 10px 40px 10px;
  270. text-align: right;
  271. }
  272. .login-box {
  273. width: 440px;
  274. background: $--color-white;
  275. box-shadow: 0px 4px 16px 0px rgba(164, 178, 203, 0.15);
  276. border-radius: 8px;
  277. border: 0px solid $--color-white;
  278. box-sizing: border-box;
  279. }
  280. .login-title {
  281. padding: 52px 52px 48px 52px;
  282. }
  283. .login-title-value {
  284. font-weight: 600;
  285. font-size: 28px;
  286. color: #333E4D;
  287. line-height: 40px;
  288. text-align: left;
  289. font-style: normal;
  290. margin-bottom: 16px;
  291. }
  292. .login-title-line {
  293. width: 80px;
  294. height: 5px;
  295. background: #E3E7EE;
  296. }
  297. .login-form {
  298. padding: 0 52px;
  299. }
  300. ::v-deep.el-form {
  301. display: block;
  302. .el-form-item {
  303. width: 100%;
  304. padding: 0;
  305. margin-bottom: 28px;
  306. position: relative;
  307. }
  308. .el-input__inner {
  309. padding: 15px 15px 15px 63px;
  310. height: 52px;
  311. line-height: 52px;
  312. font-size: 16px;
  313. }
  314. .el-input__icon,
  315. .el-range-separator {
  316. line-height: 52px;
  317. font-size: 16px;
  318. }
  319. .el-input__prefix {
  320. left: 16px;
  321. }
  322. .el-input__prefix::before {
  323. content: '';
  324. top: 16px;
  325. right: -16px;
  326. height: 21px;
  327. width: 1px;
  328. background-color: $--input-border-color;
  329. position: absolute;
  330. }
  331. .el-input__icon.iconfont {
  332. font-size: 20px;
  333. color: #596d8e;
  334. }
  335. .el-input__icon.huifont-mima {
  336. opacity: 0.95;
  337. margin-left: 2px;
  338. }
  339. .image-item {
  340. .el-form-item__content {
  341. display: flex;
  342. }
  343. .el-input {
  344. width: 190px;
  345. margin-right: 12px;
  346. }
  347. .code-image {
  348. width: 131px;
  349. height: 50px;
  350. cursor: pointer;
  351. }
  352. .color-blue {
  353. color: $--color-primary;
  354. font-size: 12px;
  355. text-align: center;
  356. }
  357. }
  358. .get-code-btn {
  359. position: absolute;
  360. top: 6px;
  361. right: 30px;
  362. }
  363. }
  364. .submit {
  365. width: 100%;
  366. margin-bottom: 60px;
  367. font-weight: 600;
  368. font-size: 20px;
  369. line-height: 28px;
  370. }
  371. </style>