login.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. <template>
  2. <div class="login-box">
  3. <div class="login-title">
  4. <div class="login-title-value">{{nowTab.name}}</div>
  5. <div class="login-title-line"></div>
  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. <img v-if="codeImg" :src="codeImg" alt="图片验证码" class="code-image" @click="imgCodeFunc">
  28. </el-form-item>
  29. <el-form-item prop="phoneCode" class="phone-code" v-if="nowTab.id === 1">
  30. <el-input type="number" prefix-icon="iconfont huifont-duanxinyanzhengma"
  31. v-model="loginForm.phoneCode" placeholder="短信验证码"
  32. oninput="if(value.length > 6) value=value.slice(0, 6)">
  33. </el-input>
  34. <div class="get-code-btn">
  35. <el-button type="primary" size="samll" @click="getPhoneCode" :disabled="codeName !== '获取验证码'">
  36. {{codeName}}
  37. </el-button>
  38. </div>
  39. </el-form-item>
  40. <el-form-item prop="password" v-if="nowTab.id === 2">
  41. <el-input type="password" prefix-icon="iconfont huifont-mima" v-model="loginForm.password"
  42. :show-password="true" placeholder="请输入密码">
  43. </el-input>
  44. </el-form-item>
  45. </el-form>
  46. <el-button class="submit" type="primary" @click="loginSubmit" :loading="loginLoading">登录</el-button>
  47. </div>
  48. </div>
  49. </template>
  50. <script>
  51. import {
  52. login,
  53. getImgCode,
  54. sendPhoneCode,
  55. getUserInfo,
  56. selectOrangaized
  57. } from '@/api/loginRegister';
  58. import {
  59. setToken,
  60. setComment
  61. } from '@/uitls/auth';
  62. export default {
  63. data() {
  64. return {
  65. loginForm: {
  66. phone: '',
  67. code: '',
  68. phoneCode: '',
  69. password: ''
  70. },
  71. loginLoading: false,
  72. codeImg: '',
  73. codeName: '获取验证码', //获取验证码text
  74. isDisabled: false, //获取验证码按钮状态
  75. loginRules: {
  76. code: [{
  77. required: true,
  78. message: '请输入图片验证码',
  79. trigger: 'blur'
  80. }],
  81. phone: [{
  82. required: true,
  83. message: '请输入手机号',
  84. trigger: 'blur'
  85. }, {
  86. validator: (rule, value, callback) => {
  87. if (!/^1[123456789]\d{9}$/.test(value)) {
  88. callback(new Error("请输入正确的手机号"));
  89. } else {
  90. callback();
  91. }
  92. },
  93. trigger: 'blur'
  94. }],
  95. phoneCode: [{
  96. required: true,
  97. message: '请输入短信验证码',
  98. trigger: 'blur'
  99. }],
  100. password: [{
  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. loginSubmit() {
  166. if (this.loginLoading) return;
  167. this.loginLoading = true;
  168. this.$refs['loginForm'].validate(valid => {
  169. if (!valid) return this.loginLoading = false;
  170. this.loginFunc();
  171. })
  172. },
  173. loginFunc() {
  174. let postData = this.nowTab.id === 1 ? {
  175. phone: this.loginForm.phone,
  176. phoneCode: this.loginForm.phoneCode
  177. } : {
  178. phone: this.loginForm.phone,
  179. password: this.loginForm.password
  180. };
  181. login(postData).then(res => {
  182. if (res.state) {
  183. setToken(res.data.token);
  184. getUserInfo().then(res => {
  185. if (res.state) {
  186. let user = res.data;
  187. let organization = user.organizationList.find(node => node.contactTel ===
  188. user.phone);
  189. if (!organization) organization = user.organizationList[0];
  190. this.$store.dispatch('app/changeOrganization', organization);
  191. this.$store.dispatch('app/changeUser', user);
  192. this.$store.dispatch('app/changeMenuData', user.workarkResource ? JSON
  193. .parse(user.workarkResource) : []);
  194. setComment(user.workarkMenu ? user.workarkMenu : JSON.stringify([]));
  195. return this.successLogin('/work');
  196. } else {
  197. this.loginLoading = false;
  198. }
  199. })
  200. } else {
  201. this.loginLoading = false;
  202. }
  203. })
  204. },
  205. successLogin(url) {
  206. this.$chat.connect();
  207. this.loginLoading = false;
  208. this.$router.push(url);
  209. this.$message.success('登录成功');
  210. }
  211. }
  212. };
  213. </script>
  214. <style lang="scss" scoped>
  215. .login-tab {
  216. display: flex;
  217. border: 1px solid #bebebe;
  218. margin-bottom: 28px;
  219. height: 36px;
  220. border-radius: 4px;
  221. align-items: center;
  222. position: relative;
  223. &:before {
  224. content: '';
  225. position: absolute;
  226. background: #bebebe;
  227. width: 159px;
  228. height: 28px;
  229. border-radius: 4px;
  230. z-index: 8;
  231. transition: left 0.3s;
  232. }
  233. &.active1:before {
  234. left: 4px;
  235. }
  236. &.active2:before {
  237. left: 167px;
  238. }
  239. }
  240. .tab-item {
  241. flex: 1;
  242. text-align: center;
  243. z-index: 9;
  244. cursor: pointer;
  245. transition: color 0.3s;
  246. &.active {
  247. color: #fff;
  248. }
  249. }
  250. .login-box {
  251. width: 440px;
  252. background: $--color-white;
  253. box-shadow: 0px 4px 16px 0px rgba(164, 178, 203, 0.15);
  254. border-radius: 8px;
  255. border: 0px solid $--color-white;
  256. box-sizing: border-box;
  257. }
  258. .login-title {
  259. padding: 52px 52px 20px 52px;
  260. }
  261. .login-title-value {
  262. font-weight: 600;
  263. font-size: 28px;
  264. color: #333E4D;
  265. line-height: 40px;
  266. text-align: left;
  267. font-style: normal;
  268. margin-bottom: 16px;
  269. }
  270. .login-title-line {
  271. width: 80px;
  272. height: 5px;
  273. background: #E3E7EE;
  274. }
  275. .login-form {
  276. padding: 0 52px;
  277. }
  278. ::v-deep.el-form {
  279. display: block;
  280. .el-form-item {
  281. width: 100%;
  282. padding: 0;
  283. margin-bottom: 28px;
  284. position: relative;
  285. }
  286. .el-input__inner {
  287. padding: 15px 15px 15px 63px;
  288. height: 52px;
  289. line-height: 52px;
  290. font-size: 16px;
  291. }
  292. .el-input__icon,
  293. .el-range-separator {
  294. line-height: 52px;
  295. font-size: 16px;
  296. }
  297. .el-input__prefix {
  298. left: 16px;
  299. }
  300. .el-input__prefix::before {
  301. content: '';
  302. top: 16px;
  303. right: -16px;
  304. height: 21px;
  305. width: 1px;
  306. background-color: $--input-border-color;
  307. position: absolute;
  308. }
  309. .el-input__icon.iconfont {
  310. font-size: 20px;
  311. color: #596d8e;
  312. }
  313. .el-input__icon.huifont-mima {
  314. opacity: 0.95;
  315. margin-left: 2px;
  316. }
  317. .image-item {
  318. .el-form-item__content {
  319. display: flex;
  320. }
  321. .el-input {
  322. width: 190px;
  323. margin-right: 12px;
  324. }
  325. .code-image {
  326. width: 131px;
  327. height: 50px;
  328. cursor: pointer;
  329. }
  330. }
  331. .get-code-btn {
  332. position: absolute;
  333. top: 6px;
  334. right: 30px;
  335. }
  336. }
  337. .submit {
  338. width: 100%;
  339. margin-bottom: 60px;
  340. font-weight: 600;
  341. font-size: 20px;
  342. line-height: 28px;
  343. }
  344. </style>