Prechádzať zdrojové kódy

登录背景学校自定义

zhangjie 1 rok pred
rodič
commit
4ca2ee46a7

BIN
src/assets/images/login-back.jpg


BIN
src/assets/images/qmth-logo.png


+ 0 - 0
src/assets/images/admin-logo.png → src/assets/images/system-logo.png


+ 100 - 61
src/assets/styles/login.scss

@@ -5,19 +5,69 @@
   left: 0;
   bottom: 0;
   right: 0;
-  z-index: 8;
-  background-image: url(../images/login-back.png);
+  z-index: auto;
+  overflow: auto;
+}
+.login-header {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 56px;
+  padding: 18px 24px;
+
+  display: flex;
+  align-items: center;
+
+  .logo-qmth {
+    height: 20px;
+
+    img {
+      display: block;
+      height: 100%;
+    }
+  }
+  .logo-divider {
+    width: 1px;
+    height: 18px;
+    background: #bfbfbf;
+    border-radius: 3px;
+    margin: 0 14px;
+  }
+
+  .logo-school {
+    height: 30px;
+    line-height: 30px;
+
+    img {
+      display: inline-block;
+      vertical-align: middle;
+      max-height: 100%;
+    }
+  }
+}
+.login-container {
+  position: absolute;
+  top: 56px;
+  bottom: 55px;
+  left: 0;
+  right: 0;
+  background-image: url(../images/login-back.jpg);
   background-repeat: no-repeat;
   background-size: cover;
-  overflow: auto;
+  background-position: center;
 }
+
 .login-footer {
   position: absolute;
   width: 100%;
   bottom: 0;
-  padding: 10px;
-  color: $--color-text-gray;
+  height: 55px;
+  padding: 17px 10px;
+  line-height: 22px;
+  color: #8c8c8c;
   text-align: center;
+  font-weight: 400;
 
   a {
     margin: 0 5px;
@@ -30,63 +80,51 @@
 
 .login-box {
   position: absolute;
-  width: 860px;
-  height: 514px;
+  width: 400px;
+  height: 332px;
   top: 50%;
-  left: 50%;
-  transform: translate(-50%, -50%);
-  border-radius: 20px;
+  right: 5.6%;
+  transform: translateY(-50%);
+  border-radius: 12px;
   background-color: #fff;
   overflow: hidden;
-}
-.login-theme {
-  width: 420px;
-  height: 100%;
-  border-radius: 20px;
-  background-color: #3858e0;
-  background-image: url(../images/login-theme.png);
-  background-size: 100% 100%;
-  float: left;
-  position: relative;
-
-  > h2 {
-    position: absolute;
-    width: 100%;
-    top: 60px;
-    left: 0;
-    text-align: center;
-    font-size: 25px;
-    color: #fff;
-  }
-}
-.login-body {
-  margin-left: 420px;
-  height: 100%;
-  overflow: hidden;
-  padding: 80px 75px;
+  padding: 40px;
 }
 .login-title {
   text-align: center;
-  margin-bottom: 40px;
+  margin-bottom: 20px;
   height: 40px;
   h1 {
     font-size: 21px;
     font-weight: bold;
   }
+}
+.login-menu {
+  .el-tabs__header {
+    margin-bottom: 24px;
+  }
+  .el-tabs__active-bar {
+    background-color: #262626;
+  }
+  .el-tabs__nav-wrap::after {
+    background-color: #e5e5e5;
+  }
+  .el-tabs__item {
+    font-weight: bold;
+    font-size: 20px;
+    line-height: 28px;
+    color: #d9d9d9;
+    padding: 0 12px 22px;
+    height: auto;
 
-  img {
-    display: block;
-    max-width: 160px;
-    max-height: 40px;
-    margin: 0 auto;
+    &.is-active {
+      color: #262626;
+    }
   }
 }
 .login-form {
   .login-submit-btn {
     width: 100%;
-    height: 48px;
-    border-radius: 24px;
-    font-size: 18px;
   }
   .vlcode-right {
     width: 100px;
@@ -94,26 +132,27 @@
   .vlcode-left {
     margin-right: 105px;
   }
-  .el-form-item__content {
-    border-bottom: 1px solid #e1e3eb;
-    padding-bottom: 2px;
+  .el-input__inner {
+    border-radius: 6px;
   }
   .el-form-item:last-child {
     margin-bottom: 0;
-    .el-form-item__content {
-      border: none;
-    }
+    margin-top: 36px;
   }
-  .el-form-item:nth-last-of-type(2) {
-    .el-form-item__content {
-      border: none;
+
+  .code-input {
+    .el-input__inner {
+      padding-right: 110px;
+    }
+    .el-input__suffix {
+      right: 8px;
+    }
+    .code-btn {
+      color: #5db9f9;
+    }
+    .el-icon-circle-close {
+      position: absolute;
+      right: 110px;
     }
-  }
-  .el-input__inner {
-    border: none;
-    border-radius: 0 !important;
-  }
-  .el-input__prefix {
-    left: 9px;
   }
 }

+ 3 - 0
src/assets/styles/pages.scss

@@ -1270,6 +1270,9 @@
     max-width: 160px;
     max-height: 40px;
   }
+  .bg-view {
+    max-width: 100%;
+  }
   .el-form-item {
     margin-bottom: 12px;
   }

+ 6 - 0
src/components/UploadFetchFile.vue

@@ -8,6 +8,7 @@
     ></el-input>
     <el-upload
       action="upload-url"
+      :accept="accept"
       :on-change="handleFileChange"
       :show-file-list="false"
       :auto-upload="false"
@@ -55,6 +56,11 @@ export default {
       res: {},
     };
   },
+  computed: {
+    accept() {
+      return this.format.map((item) => `.${item}`).join();
+    },
+  },
   methods: {
     checkFileFormat(fileType) {
       const _file_format = fileType.split(".").pop().toLocaleLowerCase();

+ 59 - 12
src/modules/admin/components/ModifySchool.vue

@@ -4,7 +4,7 @@
     :visible.sync="modalIsShow"
     :title="title"
     top="10vh"
-    width="600px"
+    width="640px"
     :close-on-click-modal="false"
     :close-on-press-escape="false"
     append-to-body
@@ -47,21 +47,38 @@
       </el-form-item>
       <el-form-item prop="logo" label="学校logo:">
         <UploadFetchFile
-          ref="UploadFetchFile"
+          ref="LogoUploadFetchFile"
           input-width="300px"
           :disabled="isSubmit"
           :format="['png', 'jpg']"
           @file-change="logoChange"
-          @valid-change="validChange"
+          @valid-change="logoValidChange"
         />
         <div class="mt-1">
           <p class="tips-info">logo会展示在登录页及内页;</p>
           <p class="tips-info">
-            文件必须是 jpg 或 png 格式的图片,不超过 2M 尺寸:160*40px。
+            文件必须是jpg或png格式的图片,不超过2M,推荐尺寸:160*40px。
           </p>
         </div>
-        <div class="logo-image" v-if="imgSrc">
-          <img class="logo-view" :src="imgSrc" alt="logo" />
+        <div class="logo-image" v-if="logoSrc">
+          <img class="logo-view" :src="logoSrc" alt="logo" />
+        </div>
+      </el-form-item>
+      <el-form-item prop="backgroundImage" label="登录背景:">
+        <UploadFetchFile
+          ref="BgUploadFetchFile"
+          input-width="300px"
+          :disabled="isSubmit"
+          :format="['png', 'jpg']"
+          @file-change="bgChange"
+          @valid-change="bgValidChange"
+        />
+        <div class="mt-1">
+          <p class="tips-info">背景会展示在登录页;</p>
+          <p class="tips-info">文件必须是jpg或png格式的图片,不超过2M。</p>
+        </div>
+        <div class="logo-image" v-if="bgSrc">
+          <img class="bg-view" :src="bgSrc" alt="logo" />
         </div>
       </el-form-item>
     </el-form>
@@ -85,6 +102,8 @@ const initModalForm = {
   code: "",
   logo: "",
   logoMd5: "",
+  backgroundImage: "",
+  backgroundImageMd5: "",
   initPassword: "",
   defaultSchool: false,
   hasPaperNumber: false,
@@ -114,8 +133,10 @@ export default {
       modalIsShow: false,
       isSubmit: false,
       modalForm: { ...initModalForm },
-      imgSrc: "",
+      logoSrc: "",
       logoValidInfo: {},
+      bgSrc: "",
+      bgValidInfo: {},
       rules: {
         name: [
           {
@@ -142,6 +163,17 @@ export default {
             },
           },
         ],
+        backgroundImage: [
+          {
+            validator: (rule, value, callback) => {
+              if (!this.bgValidInfo.success && this.bgValidInfo.message) {
+                return callback(new Error(this.bgValidInfo.message));
+              }
+
+              callback();
+            },
+          },
+        ],
         initPassword: password,
       },
     };
@@ -150,16 +182,21 @@ export default {
     initData(val) {
       if (val.id) {
         this.modalForm = this.$objAssign(initModalForm, val);
-        this.imgSrc = val.logo || "";
+        this.logoSrc = val.logo || "";
         this.modalForm.logo = "";
         this.modalForm.logoMd5 = "";
+        this.bgSrc = val.backgroundImage || "";
+        this.modalForm.backgroundImage = "";
+        this.modalForm.backgroundImageMd5 = "";
       } else {
-        this.imgSrc = "";
+        this.logoSrc = "";
+        this.bgSrc = "";
         this.modalForm = { ...initModalForm };
       }
       this.$refs.modalFormComp.clearValidate();
       this.$nextTick(() => {
-        this.$refs.UploadFetchFile.setAttachmentName("");
+        this.$refs.LogoUploadFetchFile.setAttachmentName("");
+        this.$refs.BgUploadFetchFile.setAttachmentName("");
       });
     },
     visibleChange() {
@@ -173,14 +210,24 @@ export default {
     },
     logoChange({ file, md5 }) {
       let uRl = window.URL || window.webkitURL;
-      this.imgSrc = uRl.createObjectURL(file);
+      this.logoSrc = uRl.createObjectURL(file);
       this.modalForm.logo = file;
       this.modalForm.logoMd5 = md5;
     },
-    validChange(res) {
+    logoValidChange(res) {
       this.logoValidInfo = res;
       this.$refs.modalFormComp.validateField("logo", () => {});
     },
+    bgChange({ file, md5 }) {
+      let uRl = window.URL || window.webkitURL;
+      this.bgSrc = uRl.createObjectURL(file);
+      this.modalForm.backgroundImage = file;
+      this.modalForm.backgroundImageMd5 = md5;
+    },
+    bgValidChange(res) {
+      this.bgValidInfo = res;
+      this.$refs.modalFormComp.validateField("backgroundImage", () => {});
+    },
     async submit() {
       const valid = await this.$refs.modalFormComp.validate();
       if (!valid) return;

+ 2 - 2
src/modules/login/fetchSmsMixins.js

@@ -21,7 +21,7 @@ export default {
   data() {
     return {
       isFetchingCode: false,
-      codeContent: "获取验证码",
+      codeContent: "获取短信验证码",
       codeWaitingTime,
       time: codeWaitingTime,
       setT: null,
@@ -77,7 +77,7 @@ export default {
     clearSetContent() {
       this.time = this.codeWaitingTime;
       wstorage.remove(this.nameWaitTime);
-      this.codeContent = "获取验证码";
+      this.codeContent = "获取短信验证码";
       this.isFetchingCode = false;
       clearInterval(this.setT);
     },

+ 114 - 143
src/modules/login/views/Login.vue

@@ -1,133 +1,116 @@
 <template>
-  <div class="login login-box">
-    <div class="login-theme"><h2>知学知考</h2></div>
-    <div class="login-body" @keyup.enter="submit('loginForm')">
-      <div class="login-title">
-        <template v-if="loginModel.schoolCode === 'admin'">
-          <img src="@/assets/images/admin-logo.png" alt="admin logo" />
-        </template>
-        <template v-else>
-          <img v-if="schoolLogo" :src="schoolLogo" alt="学校logo" />
-        </template>
-      </div>
-      <div class="login-form">
-        <el-form
-          v-if="IS_USERNAME_TYPE"
-          ref="loginForm"
-          :model="loginModel"
-          :rules="loginRules"
-        >
-          <el-form-item prop="loginName">
-            <el-input
-              v-model.trim="loginModel.loginName"
-              placeholder="请输入账号"
-              name="username"
-              clearable
-            >
-              <i class="icon icon-phone" slot="prefix"></i>
-            </el-input>
-          </el-form-item>
-          <el-form-item prop="password">
-            <el-input
-              type="password"
-              v-model.trim="loginModel.password"
-              placeholder="请输入密码"
-              clearable
-            >
-              <i class="icon icon-password" slot="prefix"></i>
-            </el-input>
-          </el-form-item>
-          <el-form-item v-if="schoolInfo.accountSmsVerify" prop="code">
-            <div class="vlcode">
-              <div class="vlcode-right">
-                <el-button
-                  style="width: 100%"
-                  type="text"
-                  @click="fetchAccountSmsCode"
-                  :disabled="isFetchingCode"
-                  >+{{ codeContent }}</el-button
-                >
-              </div>
-              <div class="vlcode-left">
-                <el-input
-                  v-model.trim="loginModel.code"
-                  placeholder="请输入手机验证码"
-                  name="code"
-                  clearable
-                >
-                  <i class="icon icon-checkcode" slot="prefix"></i>
-                </el-input>
-              </div>
-            </div>
-          </el-form-item>
-          <el-form-item prop="schoolCode"></el-form-item>
-          <el-form-item>
-            <el-button
-              class="login-submit-btn"
-              size="large"
-              type="info"
-              :disabled="isSubmit"
-              round
-              @click="submit('loginForm')"
-              >登录</el-button
-            >
-          </el-form-item>
-        </el-form>
-        <el-form v-else ref="loginForm" :model="loginModel" :rules="loginRules">
-          <el-form-item prop="mobileNumber">
-            <el-input
-              v-model.trim="loginModel.mobileNumber"
-              placeholder="请输入手机号"
-              name="mobileNumber"
-              clearable
-            >
-              <i class="icon icon-phone" slot="prefix"></i>
-            </el-input>
-          </el-form-item>
-          <el-form-item prop="code">
-            <div class="vlcode">
-              <div class="vlcode-right">
-                <el-button
-                  style="width: 100%"
-                  type="text"
-                  @click="fetchSmsCode"
-                  :disabled="isFetchingCode"
-                  >+{{ codeContent }}</el-button
-                >
-              </div>
-              <div class="vlcode-left">
-                <el-input
-                  v-model.trim="loginModel.code"
-                  placeholder="请输入手机验证码"
-                  name="code"
-                  clearable
-                >
-                  <i class="icon icon-checkcode" slot="prefix"></i>
-                </el-input>
-              </div>
-            </div>
-          </el-form-item>
-          <el-form-item prop="schoolCode"></el-form-item>
-          <el-form-item>
-            <el-button
-              class="login-submit-btn"
-              size="large"
-              type="info"
-              :disabled="isSubmit"
-              round
-              @click="submit('loginForm')"
-              >登录</el-button
-            >
-          </el-form-item>
-        </el-form>
-      </div>
-      <div v-if="schoolInfo.phoneLogin" class="login-action box-justify">
-        <div></div>
-        <el-button type="text" @click="switchLoginType">
-          <i>{{ switchBtnName }}</i>
-          <i class="el-icon-arrow-right"></i>
-        </el-button>
-      </div>
+  <div class="login login-box" @keyup.enter="submit('loginForm')">
+    <el-tabs class="login-menu" v-model="loginType">
+      <el-tab-pane label="密码登录" name="ACCOUNT"></el-tab-pane>
+      <el-tab-pane
+        v-if="schoolInfo.phoneLogin"
+        label="短信登录"
+        name="PHONE"
+      ></el-tab-pane>
+    </el-tabs>
+    <div class="login-form">
+      <el-form
+        v-if="IS_USERNAME_TYPE"
+        ref="loginForm"
+        size="large"
+        :model="loginModel"
+        :rules="loginRules"
+      >
+        <el-form-item prop="loginName">
+          <el-input
+            v-model.trim="loginModel.loginName"
+            placeholder="请输入你的账号"
+            name="username"
+            clearable
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item prop="password">
+          <el-input
+            type="password"
+            v-model.trim="loginModel.password"
+            placeholder="请输入你的密码"
+            name="password"
+            clearable
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item v-if="schoolInfo.accountSmsVerify" prop="code">
+          <el-input
+            v-model.trim="loginModel.code"
+            placeholder="请输入手机验证码"
+            name="code"
+            clearable
+            class="code-input"
+          >
+            <template slot="suffix">
+              <el-button
+                class="code-btn"
+                type="text"
+                size="medium"
+                :disabled="isFetchingCode"
+                @click="fetchAccountSmsCode"
+                >{{ codeContent }}</el-button
+              >
+            </template>
+          </el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button
+            class="login-submit-btn"
+            type="info"
+            :disabled="isSubmit"
+            @click="submit('loginForm')"
+            >登录</el-button
+          >
+        </el-form-item>
+      </el-form>
+      <el-form
+        v-else
+        ref="loginForm"
+        size="large"
+        :model="loginModel"
+        :rules="loginRules"
+      >
+        <el-form-item prop="mobileNumber">
+          <el-input
+            v-model.trim="loginModel.mobileNumber"
+            placeholder="请输入你的手机号"
+            name="mobileNumber"
+            clearable
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item prop="code">
+          <el-input
+            v-model.trim="loginModel.code"
+            placeholder="请输入你的验证码"
+            name="code"
+            clearable
+            class="code-input"
+          >
+            <template slot="suffix">
+              <el-button
+                class="code-btn"
+                type="text"
+                size="medium"
+                :disabled="isFetchingCode"
+                @click.stop="fetchSmsCode"
+                >{{ codeContent }}</el-button
+              >
+            </template>
+          </el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button
+            class="login-submit-btn"
+            type="info"
+            :disabled="isSubmit"
+            @click="submit('loginForm')"
+            >登录</el-button
+          >
+        </el-form-item>
+      </el-form>
     </div>
 
     <!-- 修改密码 -->
@@ -191,7 +174,6 @@ export default {
       userInfo: {},
       roles: [],
       isSubmit: false,
-      schoolLogo: "",
       loginType: "ACCOUNT",
       schoolInfo: {
         accountSmsVerify: false,
@@ -229,15 +211,11 @@ export default {
       this.$ls.set("schoolLogo", data.logo);
       this.$ls.set("schoolName", data.name);
       this.$parent.version = data.version || "";
-      this.schoolLogo = data.logo;
+      this.$parent.schoolInfo = data;
       this.schoolInfo = data;
       this.loginModel.schoolCode = data.schoolCode;
       this.$ls.set("schoolInfo", data);
     },
-    switchLoginType() {
-      if (!this.schoolInfo.phoneLogin) return;
-      this.loginType = this.loginType === "ACCOUNT" ? "PHONE" : "ACCOUNT";
-    },
     async submit(name) {
       const valid = await this.$refs[name].validate().catch(() => {});
       if (!valid) return;
@@ -353,16 +331,10 @@ export default {
       });
     },
     async fetchSmsCode() {
-      const validAll = [
-        this.checkField("mobileNumber"),
-        this.checkField("schoolCode"),
-      ];
-
       let result = true;
-      await Promise.all(validAll).catch(() => {
+      await this.checkField("mobileNumber").catch(() => {
         result = false;
       });
-
       if (!result) return;
 
       this.isFetchingCode = true;
@@ -396,7 +368,6 @@ export default {
     async fetchAccountSmsCode() {
       const validAll = [
         this.checkField("loginName"),
-        this.checkField("schoolCode"),
         this.checkField("password"),
       ];
 

+ 25 - 1
src/modules/login/views/LoginHome.vue

@@ -1,6 +1,17 @@
 <template>
   <div class="login-home">
-    <router-view></router-view>
+    <div class="login-header">
+      <div class="logo-qmth">
+        <img src="@/assets/images/qmth-logo.png" alt="qmth logo" />
+      </div>
+      <div class="logo-divider"></div>
+      <div v-if="schoolInfo.logo" class="logo-school">
+        <img :src="schoolInfo.logo" alt="学校logo" />
+      </div>
+    </div>
+    <div class="login-container" :style="containerStyles">
+      <router-view></router-view>
+    </div>
     <div class="login-footer">
       <p>
         <a href="http://www.qmth.com.cn" target="_blank"
@@ -21,8 +32,21 @@ export default {
   data() {
     return {
       version: "",
+      schoolInfo: {
+        logo: "",
+        backgroundImageUrl: "",
+      },
     };
   },
+  computed: {
+    containerStyles() {
+      return this.schoolInfo.backgroundImageUrl
+        ? {
+            backgroundImage: `url(${this.schoolInfo.backgroundImageUrl})`,
+          }
+        : {};
+    },
+  },
   methods: {},
 };
 </script>

+ 28 - 26
src/modules/login/views/SelectSchool.vue

@@ -1,31 +1,33 @@
 <template>
   <div class="select-school login login-box">
-    <div class="login-theme"></div>
-    <div class="login-body">
-      <div class="login-title">
-        <h1>选择学校</h1>
-      </div>
-      <div class="school-form">
-        <el-form ref="modalFormComp" :model="modalForm" :rules="rules">
-          <el-form-item prop="schoolId">
-            <school-select
-              v-model="modalForm.schoolId"
-              style="width: 100%"
-              @change="schoolChange"
-            ></school-select>
-          </el-form-item>
-          <el-form-item>
-            <el-button style="width: 100%" type="primary" @click="confirm"
-              >进入学校</el-button
-            >
-          </el-form-item>
-          <el-form-item>
-            <el-button style="width: 100%" type="warning" @click="toAdmin"
-              >进入超管中心<i class="el-icon-arrow-right"></i
-            ></el-button>
-          </el-form-item>
-        </el-form>
-      </div>
+    <div class="login-title">
+      <h1>选择学校</h1>
+    </div>
+    <div class="login-form">
+      <el-form
+        ref="modalFormComp"
+        size="large"
+        :model="modalForm"
+        :rules="rules"
+      >
+        <el-form-item prop="schoolId">
+          <school-select
+            v-model="modalForm.schoolId"
+            style="width: 100%"
+            @change="schoolChange"
+          ></school-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button style="width: 100%" type="primary" @click="confirm"
+            >进入学校</el-button
+          >
+        </el-form-item>
+        <el-form-item>
+          <el-button style="width: 100%" type="warning" @click="toAdmin"
+            >进入超管中心<i class="el-icon-arrow-right"></i
+          ></el-button>
+        </el-form-item>
+      </el-form>
     </div>
   </div>
 </template>