Login.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <template>
  2. <div class="login login-box">
  3. <div class="login-body" @keyup.enter="submit('loginForm')">
  4. <div class="login-title">
  5. <img v-if="schoolLogo" :src="schoolLogo" alt="学校logo" />
  6. <h1 v-else>分布式印刷</h1>
  7. </div>
  8. <div class="login-form">
  9. <el-form ref="loginForm" :model="loginModel" :rules="loginRules">
  10. <el-form-item prop="loginName">
  11. <el-input
  12. v-model.trim="loginModel.loginName"
  13. placeholder="请输入账号"
  14. clearable
  15. >
  16. <i class="icon icon-user" slot="prefix"></i>
  17. </el-input>
  18. </el-form-item>
  19. <el-form-item prop="password">
  20. <el-input
  21. type="password"
  22. v-model.trim="loginModel.password"
  23. placeholder="请输入密码"
  24. clearable
  25. >
  26. <i class="icon icon-lock" slot="prefix"></i
  27. ></el-input>
  28. </el-form-item>
  29. <el-form-item prop="code" v-if="smsCodeRequired">
  30. <div class="vlcode">
  31. <div class="vlcode-right">
  32. <el-button
  33. style="width:100%;"
  34. :type="isFetchingCode ? 'default' : 'primary'"
  35. @click="fetchSmsCode"
  36. :disabled="isFetchingCode"
  37. >{{ codeContent }}</el-button
  38. >
  39. </div>
  40. <div class="vlcode-left">
  41. <el-input
  42. v-model.trim="loginModel.code"
  43. placeholder="请输入手机验证码"
  44. clearable
  45. ></el-input>
  46. </div>
  47. </div>
  48. </el-form-item>
  49. <el-form-item prop="schoolCode"></el-form-item>
  50. <el-form-item>
  51. <el-button
  52. style="width:100%;"
  53. type="primary"
  54. :disabled="isSubmit"
  55. @click="submit('loginForm')"
  56. >登录</el-button
  57. >
  58. </el-form-item>
  59. </el-form>
  60. </div>
  61. </div>
  62. <div class="login-shadow-top"></div>
  63. <div class="login-shadow-bottom"></div>
  64. <!-- 修改密码 -->
  65. <reset-pwd :user-password="loginModel.password" ref="ResetPwd"></reset-pwd>
  66. </div>
  67. </template>
  68. <script>
  69. import { password, smscode } from "@/plugins/formRules";
  70. import {
  71. login,
  72. getSmsCode,
  73. getSchoolInfo,
  74. getSysConfig,
  75. getSysTime
  76. } from "../api";
  77. import { Base64 } from "@/plugins/crypto";
  78. import ResetPwd from "@/modules/base/components/ResetPwd";
  79. import { ORG_CODE } from "@/constants/app";
  80. import { initSyncTime } from "@/plugins/syncServerTime";
  81. const wstorage = {
  82. set(key, value, expire = null) {
  83. window.localStorage.setItem(key, JSON.stringify({ value, expire }));
  84. },
  85. get(key, defaultVal = null) {
  86. const lsvalue = JSON.parse(window.localStorage.getItem(key));
  87. return lsvalue && (!lsvalue.expire || lsvalue.expire > new Date().getTime())
  88. ? lsvalue.value
  89. : defaultVal;
  90. },
  91. remove(key) {
  92. window.localStorage.removeItem(key);
  93. }
  94. };
  95. const codeWaitingTime = 60;
  96. const nameWaitTime = "login";
  97. export default {
  98. name: "login",
  99. components: { ResetPwd },
  100. data() {
  101. return {
  102. nameWaitTime,
  103. smsCodeRequired: false,
  104. loginModel: {
  105. schoolCode: ORG_CODE,
  106. loginName: "",
  107. code: "",
  108. password: ""
  109. },
  110. loginRules: {
  111. code: smscode,
  112. password,
  113. loginName: [
  114. {
  115. required: true,
  116. message: "请输入用户名",
  117. trigger: "change"
  118. }
  119. ],
  120. schoolCode: [
  121. {
  122. required: true,
  123. message: "学校编码缺失",
  124. trigger: "change"
  125. }
  126. ]
  127. },
  128. roles: [],
  129. isSubmit: false,
  130. schoolLogo: "",
  131. // code
  132. isFetchingCode: false,
  133. codeContent: "获取验证码",
  134. codeWaitingTime,
  135. time: codeWaitingTime
  136. };
  137. },
  138. mounted() {
  139. this.$ls.clear();
  140. this.setWaitingTime();
  141. this.getSchool();
  142. this.getSmsCodeRequired();
  143. this.syncServerTime();
  144. },
  145. methods: {
  146. async syncServerTime() {
  147. const time = await getSysTime();
  148. initSyncTime(time);
  149. },
  150. async getSmsCodeRequired() {
  151. const data = await getSysConfig("sys.code.enable");
  152. this.smsCodeRequired = data.configValue === "true";
  153. },
  154. async getSchool() {
  155. const data = await getSchoolInfo(ORG_CODE);
  156. this.$ls.set("schoolLogo", data.logo);
  157. this.$ls.set("schoolName", data.name);
  158. this.schoolLogo = data.logo;
  159. },
  160. async submit(name) {
  161. const valid = await this.$refs[name].validate().catch(() => {});
  162. if (!valid) return;
  163. if (this.isSubmit) return;
  164. this.isSubmit = true;
  165. const data = await login({
  166. loginName: this.loginModel.loginName,
  167. password: Base64(this.loginModel.password),
  168. code: this.smsCodeRequired ? this.loginModel.code : null,
  169. schoolCode: this.loginModel.schoolCode
  170. }).catch(() => {});
  171. this.isSubmit = false;
  172. if (!data) return;
  173. if (data.orgInfo)
  174. this.$ls.set("orgId", data.orgInfo.id, this.GLOBAL.authTimeout);
  175. if (data.schoolInfo)
  176. this.$ls.set("schoolId", data.schoolInfo.id, this.GLOBAL.authTimeout);
  177. this.$ls.set("user", data, this.GLOBAL.authTimeout);
  178. // 强制修改密码
  179. // if (!data.user.pwdUpdateTime) {
  180. // this.$refs.ResetPwd.open();
  181. // return;
  182. // }
  183. this.$ls.set("token", data.accessToken, this.GLOBAL.authTimeout);
  184. this.$store.commit("setUser", data);
  185. if (data.roleList.includes("ADMIN")) {
  186. this.$router.push({
  187. name: "SelectSchool"
  188. });
  189. } else {
  190. this.$router.push({
  191. name: "Home"
  192. });
  193. }
  194. },
  195. // code valid
  196. setWaitingTime() {
  197. let codetime = wstorage.get(this.nameWaitTime);
  198. if (codetime) {
  199. let num = Math.floor((codetime.expire - new Date().getTime()) / 1000);
  200. if (num > 0) {
  201. this.time = num;
  202. this.isFetchingCode = true;
  203. this.changeContent();
  204. }
  205. }
  206. },
  207. checkField(field) {
  208. return new Promise((resolve, reject) => {
  209. this.$refs.loginForm.validateField(field, unvalid => {
  210. if (unvalid) {
  211. reject();
  212. } else {
  213. resolve();
  214. }
  215. });
  216. });
  217. },
  218. async fetchSmsCode() {
  219. const validAll = [
  220. this.checkField("loginName"),
  221. this.checkField("password"),
  222. this.checkField("schoolCode")
  223. ];
  224. let result = true;
  225. await Promise.all(validAll).catch(() => {
  226. result = false;
  227. });
  228. if (!result) return;
  229. this.isFetchingCode = true;
  230. const data = await getSmsCode({
  231. loginName: this.loginModel.loginName,
  232. schoolCode: this.loginModel.schoolCode,
  233. password: Base64(this.loginModel.password)
  234. }).catch(() => {
  235. this.isFetchingCode = false;
  236. });
  237. if (!data) return;
  238. this.$message.success(
  239. `已向手机号【${data}】成功发送短信,请在2分钟内进行验证!`
  240. );
  241. this.changeContent();
  242. },
  243. changeContent() {
  244. if (!this.isFetchingCode) return;
  245. this.codeContent = "倒计时" + this.time + "s";
  246. const circleTime = time => {
  247. let t = setInterval(() => {
  248. if (time > 1) {
  249. time--;
  250. let expire = new Date().getTime() + time * 1000;
  251. wstorage.set(
  252. this.nameWaitTime,
  253. {
  254. time,
  255. expire
  256. },
  257. expire
  258. );
  259. this.codeContent = "倒计时" + time + "s";
  260. } else {
  261. this.time = this.codeWaitingTime;
  262. wstorage.remove(this.nameWaitTime);
  263. this.codeContent = "获取验证码";
  264. this.isFetchingCode = false;
  265. clearInterval(t);
  266. }
  267. }, 1e3);
  268. };
  269. circleTime(this.time);
  270. }
  271. }
  272. };
  273. </script>