dusenyao 1 рік тому
батько
коміт
758d2764f6

+ 9 - 0
src/api/app.js

@@ -39,6 +39,15 @@ export function GetChildSysList_CanEnter_PC(data) {
 }
 
 /**
+ * 解开访问令牌
+ * @param {object} data 请求数据
+ * @param {string} data.access_token 访问令牌
+ */
+export function ParseAccessToken(data) {
+  return http.post(`${process.env.VUE_APP_FileServer}?MethodName=login_control-ParseAccessToken`, data);
+}
+
+/**
  * 上传文件
  * @param {String} SecurityLevel 保密级别
  * @param {object} file 文件对象

+ 14 - 0
src/icons/svg/email.svg

@@ -0,0 +1,14 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+  <g clip-path="url(#clip0_3437_23238)">
+    <path d="M24 0H0V24H24V0Z" fill="white" fill-opacity="0.01" />
+    <path d="M2 19.5H22V12V4.5H12H2V12V19.5Z" stroke="#B2B2B2" stroke-width="1.5" stroke-linejoin="round" />
+    <path d="M2 4.5L12 12L22 4.5" stroke="#B2B2B2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
+    <path d="M12 4.5H2V12" stroke="#B2B2B2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
+    <path d="M22 12V4.5H12" stroke="#B2B2B2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
+  </g>
+  <defs>
+    <clipPath id="clip0_3437_23238">
+      <rect width="24" height="24" fill="white" />
+    </clipPath>
+  </defs>
+</svg>

+ 14 - 0
src/icons/svg/key.svg

@@ -0,0 +1,14 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_3437_23251)">
+<path d="M24 0H0V24H24V0Z" fill="white" fill-opacity="0.01"/>
+<path d="M24 0H0V24H24V0Z" fill="white" fill-opacity="0.01"/>
+<path d="M11.4341 12.1503C12.7052 13.398 13.2069 15.2275 12.7485 16.9443C12.2902 18.6612 10.9422 20.0021 9.21625 20.4581C7.4903 20.914 5.6511 20.415 4.39687 19.1505C2.51104 17.2082 2.53801 14.1209 4.45749 12.2115C6.377 10.3021 9.48065 10.2753 11.4332 12.1512L11.4341 12.1503Z" stroke="#B2B2B2" stroke-width="1.5" stroke-linejoin="round"/>
+<path d="M11.5 12L20 3.5" stroke="#B2B2B2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M15.1523 8.45078L17.8666 11.1508L21.0333 8.00078L18.319 5.30078L15.1523 8.45078Z" stroke="#B2B2B2" stroke-width="1.5" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_3437_23251">
+<rect width="24" height="24" fill="white"/>
+</clipPath>
+</defs>
+</svg>

+ 7 - 0
src/layouts/answer/header/index.vue

@@ -35,6 +35,13 @@ export default {
       token,
     };
   },
+  watch: {
+    '$store.state.user.access_token': {
+      handler() {
+        this.token = getToken();
+      },
+    },
+  },
   methods: {
     logout() {
       this.$store.dispatch('user/signOut');

+ 9 - 2
src/router/modules/share.js

@@ -1,8 +1,15 @@
+import ANSWER from '@/layouts/answer';
 /**
  * 分享
  */
 export const ExerciseSharePage = {
   path: '/open/share/exercise',
-  name: 'ShareExercise',
-  component: () => import('@/views/share/ShareExercise.vue'),
+  component: ANSWER,
+  children: [
+    {
+      path: '/',
+      name: 'ShareExercise',
+      component: () => import('@/views/share/ShareExercise.vue'),
+    },
+  ],
 };

+ 3 - 1
src/store/modules/user.js

@@ -7,6 +7,7 @@ const getDefaultSate = () => {
   const token = getToken();
 
   return {
+    access_token: token?.access_token ?? '',
     session_id: token?.session_id ?? '',
     user_code: token?.user_code ?? '',
     user_real_name: token?.user_real_name ?? '',
@@ -26,7 +27,7 @@ const mutations = {
   },
   [user.SET_USER_INFO]: (
     state,
-    { user_code, user_real_name, user_type, language_type, session_id, image_url, popedom_code_list },
+    { user_code, user_real_name, user_type, language_type, session_id, image_url, popedom_code_list, access_token },
   ) => {
     state.user_code = user_code;
     state.user_real_name = user_real_name;
@@ -36,6 +37,7 @@ const mutations = {
     state.image_url = image_url;
     state.language_type = language_type || 'ZH';
     state.popedom_code_list = popedom_code_list;
+    state.access_token = access_token;
   },
 };
 

+ 1 - 1
src/views/login/index.vue

@@ -115,7 +115,7 @@ export default {
       text-align: center;
     }
 
-    :deep(.el-form) {
+    :deep .el-form {
       max-width: 400px;
       margin: 0 auto;
 

+ 137 - 46
src/views/share/ShareExercise.vue

@@ -1,20 +1,29 @@
 <template>
   <div v-show="showLogin" class="share-exercise">
     <div class="login">
+      <div class="title">登录后开始{{ isEditLink ? '编辑' : '答题' }}</div>
       <div class="login-type">
         <div :class="['login-type-item', { active: 'TEACHER' === form.user_type }]" @click="form.user_type = 'TEACHER'">
-          教师
+          我是教师
         </div>
-        <div :class="['login-type-item', { active: 'STUDENT' === form.user_type }]" @click="form.user_type = 'STUDENT'">
-          学生
+        <div
+          v-if="!isEditLink"
+          :class="['login-type-item', { active: 'STUDENT' === form.user_type }]"
+          @click="form.user_type = 'STUDENT'"
+        >
+          我是学生
         </div>
       </div>
       <el-form ref="loginForm" :model="form" :rules="rules" label-position="right">
         <el-form-item prop="user_name">
-          <el-input v-model="form.user_name" />
+          <el-input v-model="form.user_name" placeholder="邮箱地址">
+            <SvgIcon slot="prefix" size="24" icon-class="email" />
+          </el-input>
         </el-form-item>
         <el-form-item prop="password">
-          <el-input v-model="form.password" type="password" show-password />
+          <el-input v-model="form.password" type="password" show-password>
+            <SvgIcon slot="prefix" size="24" icon-class="key" />
+          </el-input>
         </el-form-item>
         <el-form-item prop="verification_code_image_text" class="verification-code">
           <el-input v-model="form.verification_code_image_text" placeholder="验证码" @keyup.enter.native="signIn" />
@@ -24,19 +33,26 @@
             @click="updateVerificationCode"
           />
         </el-form-item>
+        <el-form-item class="remember">
+          <el-checkbox v-model="is_remember">记住我</el-checkbox>
+          <span class="forgot-password">忘记密码?</span>
+        </el-form-item>
         <el-form-item>
           <el-button class="submit" type="primary" @click="signIn">登录</el-button>
         </el-form-item>
+        <el-form-item class="user-agreement">
+          <el-checkbox v-model="is_agreement">我已阅读并同意</el-checkbox>
+          <span class="link">本用户协议</span>
+        </el-form-item>
       </el-form>
     </div>
-    <div class="tip">{{ tip }}</div>
   </div>
 </template>
 
 <script>
-import { GetShareRecordInfo, PageQueryExerciseList } from '@/api/exercise';
+import { GetShareRecordInfo } from '@/api/exercise';
 import md5 from 'md5';
-import { GetVerificationCodeImage, GetLogo } from '@/api/app';
+import { GetVerificationCodeImage, GetLogo, ParseAccessToken } from '@/api/app';
 import { setConfig } from '@/utils/auth';
 
 export default {
@@ -54,6 +70,8 @@ export default {
         exercise_id: '',
       },
       showLogin: false,
+      is_remember: false, // 记住我
+      is_agreement: true, // 用户协议
       // 登录表单
       form: {
         user_type: 'STUDENT',
@@ -84,11 +102,9 @@ export default {
     };
   },
   computed: {
-    tip() {
-      if (this.share_record.access_popedom === -1) return '正在加载...';
-      return this.share_record.access_popedom === 1
-        ? '分享链接为练习题编辑链接,登录后可以开始编辑练习题'
-        : '分享链接为练习题答题链接,登录后可以开始答题';
+    // 是否编辑链接
+    isEditLink() {
+      return this.share_record.access_popedom === 1;
     },
   },
   created() {
@@ -109,17 +125,22 @@ export default {
       })
         .then(({ share_record }) => {
           this.share_record = share_record;
+          if (this.share_record.access_popedom === 1) {
+            this.form.user_type = 'TEACHER';
+          }
         })
         .then(() => {
-          PageQueryExerciseList({ page_capacity: 0, cur_page: 1, store_type: 0, search_content: '' })
-            .then(() => {
-              this.exerciseLink();
+          ParseAccessToken({ access_token: this.$store.state.user.access_token })
+            .then(({ is_effective }) => {
+              if (is_effective === 'true') {
+                this.exerciseLink();
+              } else {
+                this.updateVerificationCode();
+                this.getLogo();
+                this.showLogin = true;
+              }
             })
-            .catch(() => {
-              this.updateVerificationCode();
-              this.getLogo();
-              this.showLogin = true;
-            });
+            .catch(() => {});
         })
         .catch(() => {});
     },
@@ -180,84 +201,154 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+$basic-color: #f90;
+
 .share-exercise {
   width: 100%;
   height: 100%;
-  padding-top: 15%;
+  padding-top: 5%;
   background-color: $content-color;
 
   .login {
-    width: 50vw;
-    max-width: 1200px;
-    padding: 24px;
+    width: 465px;
+    padding: 48px 64px;
     margin: auto;
-    background-color: #f0f0f0;
+    background-color: #fff;
     border: $border;
     border-radius: 4px;
 
+    .title {
+      margin-bottom: 32px;
+      font-size: 20px;
+      color: $basic-color;
+      text-align: center;
+    }
+
     &-type {
       display: flex;
       align-items: center;
       justify-content: center;
-      width: 400px;
       padding: 2px;
       margin: 0 auto;
-      margin-bottom: 12px;
-      background-color: #fafafa;
+      margin-bottom: 24px;
+      background-color: #f0f0f0;
       border-radius: 4px;
 
       &-item {
-        width: 200px;
+        flex: 1;
         height: 36px;
         line-height: 36px;
-        color: $text-color;
+        color: #a6a6a6;
         text-align: center;
         cursor: pointer;
 
         &.active {
-          color: $main-color;
-          background-color: $fill-color;
+          color: $basic-color;
+          background-color: #fff;
           border-radius: 4px;
           box-shadow: 0 2px 8px rgba(0, 0, 0, 10%);
         }
       }
     }
 
-    :deep(.el-form) {
+    :deep .el-form {
       max-width: 400px;
       margin: 0 auto;
 
+      &-item--small.el-form-item {
+        margin-bottom: 24px;
+      }
+
+      .el-checkbox__input.is-checked {
+        + .el-checkbox__label {
+          color: #2c2c2c;
+        }
+
+        .el-checkbox__inner {
+          background-color: #fff;
+          border-color: #2c2c2c;
+
+          &::after {
+            color: #2c2c2c;
+            border-color: #2c2c2c;
+          }
+        }
+      }
+
+      .el-input {
+        &__inner {
+          height: 48px;
+          padding-left: 60px;
+          font-size: 16px;
+          line-height: 48px;
+          background-color: #fff !important;
+        }
+
+        &__prefix {
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          padding: 0 16px;
+        }
+      }
+
       .verification-code {
         .el-input {
-          width: calc(100% - 90px);
+          width: calc(100% - 138px);
           margin-right: 10px;
 
           &__inner {
+            padding-left: 15px;
             background-color: #fff;
           }
         }
 
         .el-image {
-          height: 30px;
+          height: 48px;
           vertical-align: bottom;
           cursor: pointer;
         }
       }
 
+      .remember {
+        .el-form-item__content {
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          font-size: 16px;
+
+          .forgot-password {
+            font-weight: bold;
+            color: $basic-color;
+          }
+
+          &::before,
+          &::after {
+            display: none;
+          }
+        }
+      }
+
+      .user-agreement {
+        margin-bottom: 0;
+
+        .el-checkbox__label {
+          font-size: 16px;
+        }
+
+        .link {
+          font-size: 16px;
+          color: $basic-color;
+        }
+      }
+
       .submit {
         width: 100%;
+        height: 48px;
+        background-color: $basic-color;
+        border-color: $basic-color;
       }
     }
   }
-
-  .tip {
-    width: 100%;
-    padding: 8px 0;
-    margin-top: 40px;
-    text-align: center;
-    background-color: #fff;
-    border-top: $border;
-    border-bottom: $border;
-  }
 }
 </style>