mo 1 年之前
父节点
当前提交
ce51bb17dd

+ 1 - 1
src/store/modules/users.ts

@@ -33,7 +33,7 @@ export const useUserStore = defineStore('user-store', {
     getNickname(): string {
       return this.username;
     },
-    getUserInfo(): object {
+    getUserInfo(): any {
       return this.info;
     }
   },

+ 17 - 0
src/utils/request.ts

@@ -24,6 +24,23 @@ request.interceptors.request.use(
     const userStore = useUserStore();
     const Authorization = userStore.getToken || '';
     const authHeaders: any = {};
+    console.log(userStore.getUserInfo, 'userStore');
+    if (
+      userStore.getUserInfo &&
+      userStore.getUserInfo.schoolInfos &&
+      userStore.getUserInfo.schoolInfos[0]?.id &&
+      options.data
+    ) {
+      // console.log(
+      //   userStore.getUserInfo && userStore.getUserInfo.schoolInfos[0]?.id,
+      //   ' userStore.getUserInfo && userStore.getUserInfo.schoolInfos[0]?.id',
+      //   options
+      // );
+
+      options.data['schoolId'] =
+        (userStore.getUserInfo && userStore.getUserInfo.schoolInfos[0]?.id) ||
+        '';
+    }
     if (
       Authorization &&
       !['/api-oauth/userlogin', '/api-auth/open/sendSms'].includes(url)

+ 19 - 0
src/views/classList/api.ts

@@ -1 +1,20 @@
 import request from '@/utils/request';
+/**
+ * 班级管理 - 班级列表
+ */
+export const classGroupList = (params: any) => {
+  return request.post('/edu-app/classGroup/page', {
+    data: params
+    // requestType: 'form'
+  });
+};
+
+/**
+ * 获取班级里的学生
+ */
+export const getCLassStudent = (params: any) => {
+  return request.post('/edu-app/student/page', {
+    data: params
+    // requestType: 'form'
+  });
+};

+ 85 - 0
src/views/classList/contants.ts

@@ -0,0 +1,85 @@
+export const threeYearSystem = [
+  { label: '全部年级', value: null },
+  { label: '一年级', value: 1 },
+  { label: '二年级', value: 2 },
+  { label: '三年级', value: 3 }
+];
+export const foreYearSystem = [
+  { label: '全部年级', value: null },
+  { label: '一年级', value: 1 },
+  { label: '二年级', value: 2 },
+  { label: '三年级', value: 3 },
+  { label: '四年级', value: 4 }
+];
+export const fiveYearSystem = [
+  { label: '全部年级', value: null },
+  { label: '一年级', value: 1 },
+  { label: '二年级', value: 2 },
+  { label: '三年级', value: 3 },
+  { label: '四年级', value: 4 },
+  { label: '五年级', value: 5 }
+];
+export const sixYearSystem = [
+  { label: '全部年级', value: null },
+  { label: '一年级', value: 1 },
+  { label: '二年级', value: 2 },
+  { label: '三年级', value: 3 },
+  { label: '四年级', value: 4 },
+  { label: '五年级', value: 5 },
+  { label: '六年级', value: 6 }
+];
+export const nineYearSystem = [
+  { label: '全部年级', value: null },
+  { label: '一年级', value: 1 },
+  { label: '二年级', value: 2 },
+  { label: '三年级', value: 3 },
+  { label: '四年级', value: 4 },
+  { label: '五年级', value: 5 },
+  { label: '六年级', value: 6 },
+  { label: '七年级', value: 7 },
+  { label: '八年级', value: 8 },
+  { label: '九年级', value: 9 }
+];
+export const classArray = [
+  { value: null, label: '全部班级' },
+  { value: 1, label: '1班' },
+  { value: 2, label: '2班' },
+  { value: 3, label: '3班' },
+  { value: 4, label: '4班' },
+  { value: 5, label: '5班' },
+  { value: 6, label: '6班' },
+  { value: 7, label: '7班' },
+  { value: 8, label: '8班' },
+  { value: 9, label: '9班' },
+  { value: 10, label: '10班' },
+  { value: 11, label: '11班' },
+  { value: 12, label: '12班' },
+  { value: 13, label: '13班' },
+  { value: 14, label: '14班' },
+  { value: 15, label: '15班' },
+  { value: 16, label: '16班' },
+  { value: 17, label: '17班' },
+  { value: 18, label: '18班' },
+  { value: 19, label: '19班' },
+  { value: 20, label: '20班' },
+  { value: 21, label: '21班' },
+  { value: 22, label: '22班' },
+  { value: 23, label: '23班' },
+  { value: 24, label: '24班' },
+  { value: 25, label: '25班' },
+  { value: 26, label: '26班' },
+  { value: 27, label: '27班' },
+  { value: 28, label: '28班' },
+  { value: 29, label: '29班' },
+  { value: 30, label: '30班' },
+  { value: 31, label: '31班' },
+  { value: 32, label: '32班' },
+  { value: 33, label: '33班' },
+  { value: 34, label: '34班' },
+  { value: 35, label: '35班' },
+  { value: 36, label: '36班' },
+  { value: 37, label: '37班' },
+  { value: 38, label: '38班' },
+  { value: 39, label: '39班' },
+  { value: 40, label: '40班' }
+];

二进制
src/views/classList/images/smallArrow.png


二进制
src/views/classList/images/transArrowActive.png


二进制
src/views/classList/images/transArrrow.png


+ 190 - 0
src/views/classList/index.module.less

@@ -1,3 +1,4 @@
+@img: './images';
 .listWrap {
   padding: 32px;
   background-color: #fff;
@@ -22,3 +23,192 @@
     }
   }
 }
+.btnGroup {
+  padding: 40px 0;
+
+  :global {
+    .n-button {
+      height: 47px;
+      min-width: 156px;
+    }
+  }
+}
+.resetStudentWrap {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding-top: 40px;
+  .studentTransfer {
+    position: relative;
+    .smallArrow {
+      right: 166px;
+      top: 15px;
+      position: absolute;
+      width: 12px;
+      height: 12px;
+      cursor: pointer;
+      z-index: 1000;
+    }
+
+    :global {
+      .n-legacy-transfer {
+        width: 634px;
+        min-height: 340px;
+        .n-legacy-transfer-list {
+          &:nth-child(1) {
+            .n-legacy-transfer-list-header__header {
+              &::after {
+                content: '(当前班级)';
+                font-size: 12px;
+                color: #777;
+                font-weight: 400;
+              }
+            }
+          }
+        }
+      }
+      .n-legacy-transfer-list-item {
+        &:hover {
+          background-color: #fff !important;
+        }
+      }
+      .n-legacy-transfer-list__border {
+        border: none;
+      }
+      .n-legacy-transfer-list-header__extra {
+        display: none;
+      }
+      .n-legacy-transfer-list-header {
+        display: flex;
+        flex-direction: column;
+        background: #e8f2ff;
+        align-items: flex-start;
+        height: auto;
+      }
+      .n-legacy-transfer-list-header__checkbox {
+        order: 2;
+        padding: 0 !important;
+        &::after {
+          content: '全选';
+          margin-left: 5px;
+        }
+        margin-top: 8px;
+      }
+      .n-legacy-transfer-list-header__header {
+        width: 100%;
+        padding: 14px 0;
+        font-size: 16px;
+        font-weight: 600 !important;
+        color: #131415;
+        line-height: 22px;
+        order: 1;
+        border-bottom: 1px solid rgba(0, 0, 0, 0.06);
+      }
+      .n-legacy-transfer-list {
+        padding: 0 16px;
+        min-height: 340px;
+        background: #e8f2ff;
+        border-radius: 16px 16px 0 0;
+        width: 277px;
+        .n-legacy-transfer-filter {
+          background: #e8f2ff;
+          padding: 8px 0px 0px;
+          border-bottom: none;
+        }
+        .n-input {
+          border-radius: 8px;
+          .n-input-wrapper {
+            .n-input__border {
+              border-radius: 8px;
+            }
+            .n-input__input-el {
+              height: 41px;
+              line-height: 41px;
+              background: #ffffff;
+            }
+          }
+        }
+      }
+      .n-legacy-transfer-gap {
+        width: 80px;
+        .n-button {
+          width: 34px;
+          height: 34px;
+          border-radius: 8px;
+          .n-button__state-border {
+            border: none !important;
+          }
+          &:nth-child(1) {
+            transform: rotate(180deg);
+            position: relative;
+            &:hover {
+              &::after {
+                background: url('@{img}/transArrowActive.png') no-repeat;
+                top: 0;
+                left: 0;
+
+                background-size: 34px 34px;
+              }
+            }
+            &::after {
+              position: absolute;
+              content: '';
+              width: 34px;
+              height: 34px;
+              background-color: black;
+              top: 0;
+              left: 0;
+              background: url('@{img}/transArrrow.png') no-repeat;
+              background-size: 34px 34px;
+              z-index: 100;
+            }
+          }
+          &:nth-child(2) {
+            position: relative;
+            &:hover {
+              &::after {
+                background: url('@{img}/transArrowActive.png') no-repeat;
+                top: 0;
+                left: 0;
+
+                background-size: 34px 34px;
+              }
+            }
+            &::after {
+              position: absolute;
+              content: '';
+              width: 100%;
+              height: 100%;
+              background-color: black;
+              top: 0;
+              left: 0;
+              background: url('@{img}/transArrrow.png') no-repeat;
+              background-size: 34px 34px;
+              z-index: 100;
+            }
+          }
+        }
+      }
+    }
+    .studentTransferBottom {
+      width: 100%;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      justify-content: space-between;
+
+      .bottom {
+        padding: 0 16px;
+
+        width: 277px;
+        background-color: #e8f2ff;
+
+        border-radius: 0 0 8px 8px;
+        .bottomWrap {
+          padding: 14px 0;
+          border-top: 1px solid rgba(0, 0, 0, 0.06);
+        }
+      }
+    }
+  }
+}

+ 92 - 67
src/views/classList/index.tsx

@@ -1,4 +1,4 @@
-import { defineComponent, reactive } from 'vue';
+import { defineComponent, reactive, onMounted } from 'vue';
 import styles from './index.module.less';
 import {
   NButton,
@@ -6,18 +6,36 @@ import {
   NForm,
   NFormItem,
   NImage,
+  NModal,
   NSelect,
   NSpace
 } from 'naive-ui';
 import SearchInput from '@/components/searchInput';
 import CSelect from '@/components/CSelect';
 import Pagination from '@/components/pagination';
+import { classGroupList } from './api';
+import { useUserStore } from '/src/store/modules/users';
+import ResetStudent from './modals/resetStudent';
+import {
+  sixYearSystem,
+  fiveYearSystem,
+  threeYearSystem,
+  foreYearSystem,
+  nineYearSystem,
+  classArray
+} from './contants';
 import add from './images/add.png';
+import { get } from 'http';
 export default defineComponent({
   name: 'class-classList',
   setup(props, { emit }) {
     const state = reactive({
-      searchWord: '',
+      searchForm: {
+        keyword: null as any,
+        currentClass: null,
+        currentGradeNum: null
+      },
+
       orchestraType: null,
       courseTypeCode: null,
       loading: false,
@@ -26,47 +44,51 @@ export default defineComponent({
         rows: 10,
         pageTotal: 6
       },
-      tableList: [
-        {
-          className: '三年级1班',
-          studentNum: '36',
-          lastStudy: '人教版二年级上册 | 第一单元 |【歌表演】如愿'
-        },
-        {
-          className: '三年级2班',
-          studentNum: '43',
-          lastStudy: '人教版二年级上册 | 第一单元 |【歌表演】欢乐颂'
-        },
-        {
-          className: '三年级3班',
-          studentNum: '56',
-          lastStudy: '人教版二年级上册 | 第一单元 |【歌表演】我和我的祖国'
-        },
-        {
-          className: '三年级4班',
-          studentNum: '35',
-          lastStudy: '人教版二年级上册 | 第一单元 |【歌表演】孤勇者'
-        },
-        {
-          className: '三年级5班',
-          studentNum: '42',
-          lastStudy: '人教版二年级上册 | 第一单元 |【歌表演】大雁'
-        },
-        {
-          className: '三年级1班',
-          studentNum: '38',
-          lastStudy: '人教版二年级上册 | 第一单元 |【歌表演】暗香'
-        }
-      ] as any
+      gradeNumList: [] as any,
+      tableList: [] as any,
+      studentVisible: false,
+      activeRow: null as any
     });
+
     const search = () => {
       console.log('search', state);
     };
-
+    const userInfo = useUserStore();
+    if (userInfo.getUserInfo.schoolInfos[0].gradeYear == 'THREE_YEAR_SYSTEM') {
+      state.gradeNumList = threeYearSystem;
+    } else if (
+      userInfo.getUserInfo.schoolInfos[0].gradeYear == 'FORE_YEAR_SYSTEM'
+    ) {
+      state.gradeNumList = foreYearSystem;
+    } else if (
+      userInfo.getUserInfo.schoolInfos[0].gradeYear == 'FIVE_YEAR_SYSTEM'
+    ) {
+      state.gradeNumList = fiveYearSystem;
+    } else if (
+      userInfo.getUserInfo.schoolInfos[0].gradeYear == 'SIX_YEAR_SYSTEM'
+    ) {
+      state.gradeNumList = sixYearSystem;
+    } else {
+      state.gradeNumList = nineYearSystem;
+    }
     const onReset = () => {
       console.log('search');
     };
-    const getList = () => {
+    const getList = async () => {
+      // classGroupList
+      state.loading = true;
+      try {
+        const res = await classGroupList({
+          ...state.searchForm,
+          ...state.pagination
+        });
+        state.tableList = res.data.rows;
+        state.pagination.pageTotal = res.data.total;
+        state.loading = false;
+      } catch (e) {
+        state.loading = false;
+        console.log(e);
+      }
       console.log('getList');
     };
 
@@ -74,15 +96,18 @@ export default defineComponent({
       return [
         {
           title: '班级名称',
-          key: 'className'
+          key: 'name'
         },
         {
           title: '学生人数',
-          key: 'studentNum'
+          key: 'preStudentNum'
         },
         {
           title: '上次学习',
-          key: 'lastStudy'
+          key: 'lastStudy',
+          render(row: any) {
+            return <p>{row.lastStudy ? row.lastStudy : '--'}</p>;
+          }
         },
         {
           title: '操作',
@@ -94,10 +119,12 @@ export default defineComponent({
                   <NButton type="primary" text>
                     详情
                   </NButton>
-                  <NButton type="primary" text>
-                    修改
-                  </NButton>
-                  <NButton type="primary" text>
+                  <NButton
+                    type="primary"
+                    text
+                    onClick={() => {
+                      startResetStudent(row);
+                    }}>
                     学生调整
                   </NButton>
                   <NButton type="primary" text>
@@ -113,6 +140,14 @@ export default defineComponent({
         }
       ];
     };
+
+    const startResetStudent = (row: any) => {
+      state.activeRow = row;
+      state.studentVisible = true;
+    };
+    onMounted(() => {
+      getList();
+    });
     return () => (
       <div class={styles.listWrap}>
         <div class={styles.searchList}>
@@ -121,49 +156,31 @@ export default defineComponent({
               <SearchInput
                 {...{ placeholder: '请输入班级名称' }}
                 class={styles.searchInput}
-                searchWord={state.searchWord}
+                searchWord={state.searchForm.keyword}
                 onChangeValue={(val: string) =>
-                  (state.searchWord = val)
+                  (state.searchForm.keyword = val)
                 }></SearchInput>
             </NFormItem>
 
             <NFormItem>
               <CSelect
                 {...({
-                  options: [
-                    {
-                      label: '一年级',
-                      value: 'song0'
-                    },
-                    {
-                      label: '二年级',
-                      value: 'song1'
-                    }
-                  ],
+                  options: state.gradeNumList,
                   placeholder: '全部年级',
                   clearable: true,
                   inline: true
                 } as any)}
-                v-model:value={state.orchestraType}></CSelect>
+                v-model:value={state.searchForm.currentGradeNum}></CSelect>
             </NFormItem>
             <NFormItem>
               <CSelect
                 {...({
-                  options: [
-                    {
-                      label: '1班',
-                      value: 'song0'
-                    },
-                    {
-                      label: '2班',
-                      value: 'song1'
-                    }
-                  ],
+                  options: classArray,
                   placeholder: '全部班级',
                   clearable: true,
                   inline: true
                 } as any)}
-                v-model:value={state.courseTypeCode}></CSelect>
+                v-model:value={state.searchForm.currentClass}></CSelect>
             </NFormItem>
 
             <NFormItem>
@@ -209,6 +226,14 @@ export default defineComponent({
             saveKey="orchestraRegistration-key"
           />
         </div>
+        <NModal
+          v-model:show={state.studentVisible}
+          style={{ width: '707px' }}
+          preset="card"
+          class={['modalTitle background']}
+          title={'学员调整'}>
+          <ResetStudent activeRow={state.activeRow}></ResetStudent>
+        </NModal>
       </div>
     );
   }

+ 161 - 0
src/views/classList/modals/resetStudent.tsx

@@ -0,0 +1,161 @@
+import {
+  NButton,
+  NLegacyTransfer,
+  NSpace,
+  useMessage,
+  NPopselect,
+  NImage,
+  NDropdown
+} from 'naive-ui';
+import { defineComponent, onMounted, reactive, ref } from 'vue';
+import styles from '../index.module.less';
+import smallArrow from '../images/smallArrow.png';
+import { getCLassStudent, classGroupList } from '../api';
+export default defineComponent({
+  props: {
+    activeRow: {
+      type: Object,
+      default: () => ({ id: '' })
+    }
+  },
+  name: 'resetStudent',
+  emits: ['close'],
+  setup(props, { emit }) {
+    const message = useMessage();
+    const data = reactive({
+      uploading: false
+    });
+    const options = ref([] as any);
+    const currentStudnetList = ref([] as any);
+    const chioseOptions = ref([] as any);
+    const formRef = ref();
+    const handleSubmit = async () => {
+      data.uploading = true;
+    };
+    const classList = ref([] as any);
+    console.log(props.activeRow, 'activeRow');
+    const targetClass = reactive({
+      name: '',
+      id: ''
+    });
+    //
+
+    /**
+     * 这里干3件事  1.获取当前班的学生
+     * 2.查询所有的班级列表  并且排查当前班级
+     * 3.默认选择第一个班级 并且查出此班的学生
+     */
+    const chioseStudnet = (val: any) => {
+      console.log(val);
+    };
+    const getAllClassList = async () => {
+      try {
+        const res = await classGroupList({ page: 1, rows: 9999 });
+        classList.value = res.data.rows.map((item: any) => {
+          return {
+            label: item.name,
+            key: item.id,
+            disabled: item.id == props.activeRow.id
+          };
+        });
+        if (classList.value[0].disabled) {
+          targetClass.name = classList.value[1].label;
+          targetClass.id = classList.value[1].id;
+        } else {
+          targetClass.name = classList.value[0].label;
+          targetClass.id = classList.value[0].id;
+        }
+
+        console.log(classList.value, ' classList.value');
+      } catch (e) {
+        console.log(e);
+      }
+    };
+    const getCLassStudentList = async (id: string | number) => {
+      return await getCLassStudent({
+        page: 1,
+        rows: 999,
+        classGroupId: id
+      });
+    };
+    const chioseClass = async (val: any) => {
+      classList.value.forEach((item: any) => {
+        if (item.key == val) {
+          targetClass.name = item.label;
+          targetClass.id = item.key;
+        }
+      });
+      console.log(targetClass);
+      const res = await getCLassStudentList(val);
+      chioseOptions.value = res.data.rows.map((item: any) => {
+        return item.id;
+      });
+      console.log(chioseOptions.value, 'chioseOptions.value');
+    };
+    onMounted(async () => {
+      console.log('onMounted');
+      getAllClassList();
+      const res = await getCLassStudentList(props.activeRow.id as string);
+      currentStudnetList.value = res.data.rows.map((item: any) => {
+        return {
+          label: item.nickname + '(' + item.id + ')',
+          value: item.id
+        };
+      });
+    });
+    return () => (
+      <div class={[styles.container, styles.resetStudentWrap]}>
+        <div class={styles.studentTransfer}>
+          <NDropdown
+            key="111"
+            v-model:value={targetClass.id}
+            options={classList.value}
+            onSelect={(value: any) => {
+              chioseClass(value);
+            }}
+            scrollable>
+            <NImage
+              class={styles.smallArrow}
+              src={smallArrow}
+              previewDisabled></NImage>
+          </NDropdown>
+          <NLegacyTransfer
+            source-title={props.activeRow.name}
+            target-title={targetClass.name}
+            size="large"
+            ref={formRef}
+            options={currentStudnetList.value}
+            source-filter-placeholder="请输入学生姓名"
+            target-filter-placeholder="请输入学生姓名"
+            v-model:value={chioseOptions.value}
+            virtual-scroll
+            onUpdate:value={(val: any) => {
+              chioseStudnet(val);
+            }}
+            filterable></NLegacyTransfer>
+          <div class={styles.studentTransferBottom}>
+            <div class={[styles.bottomLeft, styles.bottom]}>
+              <div class={styles.bottomWrap}>共0名学生</div>
+            </div>
+            <div class={[styles.bottomRight, styles.bottom]}>
+              <div class={styles.bottomWrap}>共0名学生</div>
+            </div>
+          </div>
+        </div>
+
+        <NSpace class={styles.btnGroup} justify="center">
+          <NButton round onClick={() => emit('close')}>
+            取消
+          </NButton>
+          <NButton
+            round
+            loading={data.uploading}
+            type="primary"
+            onClick={() => handleSave()}>
+            保存
+          </NButton>
+        </NSpace>
+      </div>
+    );
+  }
+});

+ 2 - 3
src/views/login/api.ts

@@ -14,8 +14,7 @@ export const sendSms = (params: any) => {
  * 修改密码-
  */
 export const updatePassword = (params: any) => {
-  return request.post('/edu-app/user/updatePassword', {
-    data: params,
-    requestType: 'form'
+  return request.post('/edu-app/open/user/updatePassword', {
+    data: params
   });
 };

+ 10 - 8
src/views/login/components/forgotPassword.tsx

@@ -19,7 +19,7 @@ import { storage } from '@/utils/storage';
 import { useUserStore } from '/src/store/modules/users';
 import { sendSms, updatePassword } from '../api';
 interface FormState {
-  username: string;
+  mobile: string;
   password: string;
   grant_type: string;
   loginType: string;
@@ -42,7 +42,7 @@ export default defineComponent({
     const showPwd2 = ref(false);
     const userStore = useUserStore();
     const formInline = reactive({
-      username: '',
+      mobile: '',
       password: '',
       password1: '',
       code: '',
@@ -72,12 +72,14 @@ export default defineComponent({
           loading.value = true;
           try {
             await updatePassword({
-              ...formInline
+              ...formInline,
+              clientType: 'TEACHER'
             });
             message.success('修改成功');
             loading.value = false;
+
+            emit('changType');
             return false;
-            // emit('changType');
           } catch (e: any) {
             loading.value = false;
             message.error(e.msg);
@@ -90,14 +92,14 @@ export default defineComponent({
     };
 
     const sendMessage = async () => {
-      if (!formInline.username) {
+      if (!formInline.mobile) {
         message.error('请输入手机号');
         return;
       }
       try {
         const res = await sendSms({
           clientId: 'cooleshow-teacher',
-          mobile: formInline.username,
+          mobile: formInline.mobile,
           type: 'PASSWORD'
         });
         checkTimeOut();
@@ -132,13 +134,13 @@ export default defineComponent({
           size="large"
           model={formInline}>
           <NFormItem
-            path="username"
+            path="mobile"
             rule={[
               { required: true, message: '请输入手机号', trigger: 'blur' }
             ]}>
             <NInput
               maxlength={11}
-              v-model:value={formInline.username}
+              v-model:value={formInline.mobile}
               placeholder="请输入手机号">
               {{
                 prefix: () => (