Jelajahi Sumber

Merge branch 'online' of http://git.dayaedu.com/lex/classroom-instruments into online

mo 1 tahun lalu
induk
melakukan
3cc0b36296

+ 2 - 0
src/components/layout/index.tsx

@@ -38,6 +38,7 @@ export default defineComponent({
     const previewItem = ref({});
     const directionType = ref('left');
     const showClass = ref(false);
+
     const showModalBeat = ref(false);
     const showModalTone = ref(false);
     const showModalTime = ref(false);
@@ -703,6 +704,7 @@ export default defineComponent({
             }}
           />
         </NModal>
+
         {/* 弹窗查看 */}
         <PreviewWindow
           v-model:show={previewModal.value}

+ 63 - 0
src/components/layout/modals/update-password.module.less

@@ -0,0 +1,63 @@
+.updatePassword {
+  padding: 0px 40px 30px;
+
+  .tips {
+    padding-bottom: 12px;
+    font-size: 18px;
+    color: #777777;
+  }
+
+  .phoneContainer {
+    :global {
+      .n-form-item-feedback-wrapper {
+        min-height: 12px;
+      }
+    }
+  }
+
+  :global {
+    .n-form-item .n-form-item-label {
+      font-size: 18px;
+      color: #777777;
+    }
+  }
+
+
+  .phone {
+    font-weight: bold;
+  }
+
+  .updateBtnGroup {
+    width: 100%;
+    padding: 0;
+    justify-content: center !important;
+    text-align: center;
+
+    :global {
+      .n-button {
+        height: 48px !important;
+        min-width: 80%;
+      }
+    }
+  }
+
+  .sendInput {
+    :global {
+      .n-input-wrapper {
+        padding-right: 0;
+      }
+    }
+
+    .sendMsg {
+      width: 128px;
+      // height: 64px;
+      background: #198cfe;
+      // border-radius: 0px 8px 8px 0px;
+      font-size: 20px;
+      font-family: PingFangSC-Medium, PingFang SC;
+      font-weight: 500;
+      color: #ffffff;
+      line-height: 62px;
+    }
+  }
+}

+ 209 - 0
src/components/layout/modals/update-password.tsx

@@ -0,0 +1,209 @@
+import { defineComponent, onMounted, reactive, ref } from 'vue';
+import styles from './update-password.module.less';
+import {
+  NButton,
+  NForm,
+  NFormItem,
+  NInput,
+  NSelect,
+  NSpace,
+  useMessage
+} from 'naive-ui';
+import { useRouter } from 'vue-router';
+import { useUserStore } from '/src/store/modules/users';
+import { gradeToCN } from '/src/utils/contants';
+import { sendSms, updatePassword } from '/src/views/login/api';
+export default defineComponent({
+  name: 'train-update',
+  emits: ['close', 'submit'],
+  setup(props, { emit }) {
+    const message = useMessage();
+    const userStore = useUserStore();
+    const forms = reactive({
+      mobile: userStore.getUserInfo.phone || '',
+      password: null,
+      rePassword: null,
+      clientType: 'TEACHER',
+      code: null
+    });
+
+    const validatePass2 = (rule: any, value: any, callback: any): any => {
+      const reg = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/;
+      if (value === '' || !value) {
+        callback(new Error('请再次输入新密码'));
+      } else if (value !== forms.password) {
+        callback(new Error('两次输入密码不一致'));
+      } else if (!reg.test(value)) {
+        callback(new Error('密码为6-20位数字和字母组合'));
+      } else {
+        callback();
+      }
+    };
+    const validatePass = (rule: any, value: any, callback: any): any => {
+      const reg = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/;
+      if (value === '' || !value) {
+        callback(new Error('请输入新密码'));
+      } else if (!reg.test(value)) {
+        callback(new Error('密码为6-20位数字和字母组合'));
+      } else {
+        callback();
+      }
+    };
+
+    const gotoClassPage = () => {
+      formsRef.value.validate(async (error: any) => {
+        if (error) return;
+
+        if (forms.password !== forms.rePassword) {
+          message.error('两次输入密码不一致');
+          return;
+        }
+
+        await updatePassword({
+          mobile: forms.mobile,
+          password: forms.password,
+          clientType: 'TEACHER',
+          code: forms.code
+        });
+
+        message.success('更新成功');
+        emit('submit');
+      });
+    };
+
+    const formsRef = ref();
+
+    const isDisabledCode = ref(false);
+    const starTimer = ref(60);
+    const codeName = '发送短信';
+    const sendMessage = async () => {
+      if (!forms.mobile) {
+        message.error('请输入手机号');
+        return;
+      }
+      try {
+        await sendSms({
+          clientId: 'cooleshow-teacher',
+          mobile: forms.mobile,
+          type: 'LOGIN'
+        });
+        checkTimeOut();
+      } catch (e) {
+        console.log(e);
+      }
+    };
+
+    const checkTimeOut = () => {
+      if (isDisabledCode.value) {
+        return;
+      }
+      isDisabledCode.value = true;
+      const tiemr = setInterval(() => {
+        starTimer.value--;
+        console.log(starTimer.value);
+        if (starTimer.value <= 0) {
+          isDisabledCode.value = false;
+          clearInterval(tiemr);
+        }
+      }, 1000);
+    };
+
+    onMounted(async () => {
+      //
+    });
+    return () => (
+      <div class={styles.updatePassword}>
+        <p class={styles.tips}>
+          检测到您尚未修改默认密码,为了您的账户安全,请重新设置登录密码
+        </p>
+        <NForm
+          labelAlign="right"
+          labelPlacement="left"
+          labelWidth={'auto'}
+          ref={formsRef}
+          model={forms}
+          requireMarkPlacement="left">
+          <NFormItem
+            path="currentClass"
+            label="手机号"
+            class={styles.phoneContainer}>
+            <p class={styles.phone}>{forms.mobile}</p>
+          </NFormItem>
+          <NFormItem
+            path="password"
+            label="新密码"
+            rule={[
+              {
+                validator: validatePass,
+                trigger: 'blur',
+                required: true
+              }
+            ]}>
+            <NInput
+              v-model:value={forms.password}
+              clearable
+              type="password"
+              show-password-on="click"
+              placeholder={'请输入新密码'}
+            />
+          </NFormItem>
+          <NFormItem
+            path="rePassword"
+            label="再次输入"
+            rule={[
+              {
+                validator: validatePass2,
+                trigger: 'blur',
+                required: true
+              }
+            ]}>
+            <NInput
+              v-model:value={forms.rePassword}
+              clearable
+              type="password"
+              show-password-on="click"
+              placeholder={'再次输入新密码'}
+            />
+          </NFormItem>
+          <NFormItem
+            path="code"
+            label="验证码"
+            rule={[
+              {
+                required: true,
+                message: '请输入验证码',
+                trigger: 'blur'
+              }
+            ]}>
+            <NInput
+              v-model:value={forms.code}
+              placeholder={'请输入验证码'}
+              clearable
+              class={styles.sendInput}
+              maxlength={6}>
+              {{
+                suffix: () => (
+                  <NButton
+                    class={styles.sendMsg}
+                    disabled={isDisabledCode.value}
+                    onClick={() => sendMessage()}>
+                    {isDisabledCode.value ? starTimer.value + 'S' : codeName}
+                  </NButton>
+                )
+              }}
+            </NInput>
+          </NFormItem>
+          <div class={styles.updateBtnGroup}>
+            <NButton
+              strong
+              type="primary"
+              round
+              onClick={() => gotoClassPage()}>
+              确认
+            </NButton>
+          </div>
+        </NForm>
+      </div>
+    );
+  }
+});

+ 60 - 61
src/views/attend-class/index.tsx

@@ -86,7 +86,7 @@ export default defineComponent({
     const parentContainer = reactive({
       width: '100vw'
     });
-    const NPopoverRef = ref()
+    const NPopoverRef = ref();
     const setContainer = () => {
       const min = Math.min(screen.width, screen.height);
       const max = Math.max(screen.width, screen.height);
@@ -114,7 +114,7 @@ export default defineComponent({
 
     onUnmounted(() => {
       handleInit(1);
-      window.removeEventListener("resize", resetSize);
+      window.removeEventListener('resize', resetSize);
     });
 
     const data = reactive({
@@ -223,7 +223,7 @@ export default defineComponent({
           throttleScale: 0,
           throttleRotate: 0
         });
-        console.log('initMoveable完毕',moveable)
+        console.log('initMoveable完毕', moveable);
         moveable
           .on('dragStart', ({ target, clientX, clientY }) => {
             console.log('dragStart');
@@ -245,8 +245,8 @@ export default defineComponent({
               // clientY
             }) => {
               isDragIng.value = true;
-              if(NPopoverRef.value){
-                NPopoverRef.value.setShow(false)
+              if (NPopoverRef.value) {
+                NPopoverRef.value.setShow(false);
               }
 
               const subdEl = document.getElementById(
@@ -328,7 +328,7 @@ export default defineComponent({
                 // 往又出
                 directionType.value = 'left';
               }
-              console.log(target.style.left)
+              console.log(target.style.left);
               isDragIng.value = false;
               // 在这里进行动画
               if (boxBoundaryInfo.isBoundary) {
@@ -362,38 +362,32 @@ export default defineComponent({
       data.detailId = props.detailId || query.detailId;
       data.classGroupId = props.classGroupId || query.classGroupId;
 
-
       const subdEl = document.getElementById(`moveNPopoverA`) as HTMLDivElement;
       initBoundaryWrap(subdEl, boxBoundaryInfo);
       initBoxRectInfo(subdEl, boxBoundaryInfo);
 
-
       window.addEventListener('message', iframeHandle);
       getDetail();
-      window.addEventListener("resize", resetSize);
+      window.addEventListener('resize', resetSize);
     });
 
-    const resetSize = ()=>{
+    const resetSize = () => {
       const subdEl = document.getElementById(`moveNPopoverA`) as HTMLDivElement;
-      subdEl.style.display = 'none'
-
-
+      subdEl.style.display = 'none';
 
-        boxBoundaryInfo.isBoundary = true;
-        boxBoundaryInfo.isBoundaryType= 'right'
-        if(NPopoverRef.value){
-          NPopoverRef.value.setShow(false)
-        }
-
-        setTimeout(()=>{
-
-          subdEl.style.transition = ''
-          initBoxRectInfo(subdEl, boxBoundaryInfo);
-          initBoundaryWrap(subdEl, boxBoundaryInfo);
-          subdEl.style.display = 'block'
-        },100)
+      boxBoundaryInfo.isBoundary = true;
+      boxBoundaryInfo.isBoundaryType = 'right';
+      if (NPopoverRef.value) {
+        NPopoverRef.value.setShow(false);
+      }
 
-    }
+      setTimeout(() => {
+        subdEl.style.transition = '';
+        initBoxRectInfo(subdEl, boxBoundaryInfo);
+        initBoundaryWrap(subdEl, boxBoundaryInfo);
+        subdEl.style.display = 'block';
+      }, 100);
+    };
 
     const initBoundaryWrap = (target: any, wrapInfo: any) => {
       target.addEventListener('mouseenter', () => {
@@ -412,7 +406,7 @@ export default defineComponent({
         rate(target, 0);
       });
       target.addEventListener('mouseleave', () => {
-          console.log('mouseleave',wrapInfo.isBoundary)
+        console.log('mouseleave', wrapInfo.isBoundary);
         if (wrapInfo.isBoundary) {
           // 如果在边框 就得还原 元素位置 还原完毕后 去除transition
           if (wrapInfo.isBoundaryType == 'left') {
@@ -511,7 +505,6 @@ export default defineComponent({
       wrapInfo.subWidth = RectInfo.width;
       wrapInfo.subHeight = RectInfo.height;
       target.style.transition = '.3s';
-
     };
     const onFullScreen = () => {
       if (data.type === 'preview') {
@@ -1204,35 +1197,41 @@ export default defineComponent({
           transformOrigin="center"
           v-model:show={data.modelAttendStatus}
           preset="card"
-          class={styles.attendClassModal}
-          title={'课后作业'}>
-          <div class={styles.modelAttendContent}>{data.modalAttendMessage}</div>
-          <NSpace class={styles.modelAttendBtnGroup}>
-            <NButton
-              type="default"
-              round
-              onClick={() => {
-                data.modelAttendStatus = false;
-                handleStop();
-                // if (state.application) {
-                //   emit('close');
-                // } else {
-                //   window.close();
-                // }
-                data.modelAttendStatus = false;
-              }}>
-              暂不布置
-            </NButton>
-            <NButton
-              type="primary"
-              round
-              onClick={() => {
-                data.modelTrainStatus = true;
-                data.modelAttendStatus = false;
-              }}>
-              布置
-            </NButton>
-          </NSpace>
+          // class={styles.attendClassModal}
+          title={'课后作业'}
+          class={['modalTitle', styles.removeVisiable]}>
+          <div class={styles.studentRemove}>
+            <p>{data.modalAttendMessage}</p>
+            {/* <div class={styles.modelAttendContent}>
+              {data.modalAttendMessage}
+            </div> */}
+            <NSpace class={styles.btnGroupModal}>
+              <NButton
+                type="default"
+                round
+                onClick={() => {
+                  data.modelAttendStatus = false;
+                  handleStop();
+                  // if (state.application) {
+                  //   emit('close');
+                  // } else {
+                  //   window.close();
+                  // }
+                  data.modelAttendStatus = false;
+                }}>
+                暂不布置
+              </NButton>
+              <NButton
+                type="primary"
+                round
+                onClick={() => {
+                  data.modelTrainStatus = true;
+                  data.modelAttendStatus = false;
+                }}>
+                布置
+              </NButton>
+            </NSpace>
+          </div>
         </NModal>
 
         {/* 训练设置 */}
@@ -1375,6 +1374,9 @@ export default defineComponent({
             <p>{data.removeContent}</p>
 
             <NSpace class={styles.btnGroupModal} justify="center">
+              <NButton round onClick={() => (data.removeVisiable = false)}>
+                取消
+              </NButton>
               <NButton
                 round
                 type="primary"
@@ -1395,9 +1397,6 @@ export default defineComponent({
                 }}>
                 确定
               </NButton>
-              <NButton round onClick={() => (data.removeVisiable = false)}>
-                取消
-              </NButton>
             </NSpace>
           </div>
         </NModal>

+ 9 - 0
src/views/home/api.ts

@@ -17,3 +17,12 @@ export const classGroupList = (params: any) => {
     data: params
   });
 };
+
+/**
+ * 首页 - 修改密码
+ */
+export const updatePassword = (params: any) => {
+  return request.post('/edu-app/open/user/updatePassword', {
+    data: params
+  });
+};

+ 4 - 0
src/views/home/index.module.less

@@ -867,4 +867,8 @@
     }
   }
 
+}
+
+.showUpdatePassword {
+  width: 514px;
 }

+ 40 - 4
src/views/home/index.tsx

@@ -59,8 +59,9 @@ import toneImage from '@/components/layout/images/toneImage.png';
 import { px2vw } from '/src/utils';
 import PlaceholderTone from '@/components/layout/modals/placeholderTone';
 import { state } from '/src/state';
-import { fscreen} from '@/utils/index'
+import { fscreen } from '@/utils/index';
 import PreviewWindow from '../preview-window';
+import UpdatePassword from '/src/components/layout/modals/update-password';
 import { state as globalState } from '/src/state';
 export const formatDateToDay = () => {
   const hours = dayjs().hour();
@@ -80,6 +81,7 @@ export default defineComponent({
     const message = useMessage();
     const router = useRouter();
     const userStore = useUserStore();
+    const showUpdatePassword = ref(false);
     const showModalBeat = ref(false);
     const showModalTone = ref(false);
     const showModalTime = ref(false);
@@ -316,7 +318,12 @@ export default defineComponent({
         };
       });
       getVersion();
-      forms.showGuide = true;
+
+      if (!userStore.getUserInfo.account.updatePasswordFlag) {
+        showUpdatePassword.value = true;
+      } else {
+        forms.showGuide = true;
+      }
     });
 
     const formsRef = ref();
@@ -344,9 +351,11 @@ export default defineComponent({
                 subjectId: forms.subjectId,
                 detailId: forms.unit
               };
-              globalState.application = window.matchMedia('(display-mode: standalone)').matches
+              globalState.application = window.matchMedia(
+                '(display-mode: standalone)'
+              ).matches;
               // 加全屏
-              fscreen()
+              fscreen();
             } else {
               const { href } = router.resolve({
                 path: '/attend-class',
@@ -796,6 +805,33 @@ export default defineComponent({
         />
 
         {forms.showGuide ? <HomeGuide></HomeGuide> : null}
+
+        <NModal
+          v-model:show={showUpdatePassword.value}
+          class={['modalTitle', styles.showUpdatePassword]}
+          style="--n-title-font-weight: 600;"
+          preset="card"
+          title={'修改密码'}
+          closable={false}
+          maskClosable={false}
+          closeOnEsc={false}>
+          <UpdatePassword
+            onSubmit={() => {
+              // 密码更新成功
+              showUpdatePassword.value = true;
+              forms.showGuide = true;
+
+              userStore.logout().then(() => {
+                // 移除标签页
+                router
+                  .replace({
+                    name: 'login'
+                  })
+                  .finally(() => location.reload());
+              });
+            }}
+          />
+        </NModal>
       </div>
     );
   }

+ 5 - 4
src/views/login/components/codeLogin.tsx

@@ -43,9 +43,9 @@ export default defineComponent({
     const isDisabledCode = ref(false);
     const starTimer = ref(60);
     const codeName = '发送短信';
-    const formInlineHistory = storage.get("userInfo-teacher");
+    const formInlineHistory = storage.get('userInfo-teacher');
     if (formInlineHistory) {
-      formInline.username =JSON.parse(formInlineHistory).username;
+      formInline.username = JSON.parse(formInlineHistory).username;
     }
     const handleSubmit = async () => {
       formRef.value.validate(async (errors: any) => {
@@ -53,7 +53,7 @@ export default defineComponent({
           const { username, password } = formInline;
           message.loading('登录中...');
           loading.value = true;
-          storage.set('userInfo-teacher', JSON.stringify({username}));
+          storage.set('userInfo-teacher', JSON.stringify({ username }));
           const params: FormState = {
             username,
             password,
@@ -168,6 +168,7 @@ export default defineComponent({
                 placeholder="请输入验证码"
                 inputProps={{ autocomplete: 'off' }}
                 class={styles.sendInput}
+                maxlength={6}
                 onKeydown={(e: KeyboardEvent) => {
                   if (e.code === 'Enter' || e.code === 'NumpadEnter') {
                     handleSubmit();
@@ -182,7 +183,7 @@ export default defineComponent({
                       class={styles.sendMsg}
                       disabled={isDisabledCode.value}
                       onClick={() => sendMessage()}>
-                      {isDisabledCode.value ? starTimer.value+'S' : codeName}
+                      {isDisabledCode.value ? starTimer.value + 'S' : codeName}
                     </NButton>
                   )
                 }}