Bladeren bron

Merge branch 'iteration-20240506' into jenkins-dev

lex 1 jaar geleden
bovenliggende
commit
c8ceda964d

+ 57 - 57
src/components/TheMessageDialog/index.tsx

@@ -1,57 +1,57 @@
-import { NButton, NSpace } from 'naive-ui';
-import { PropType, defineComponent } from 'vue';
-import styles from './index.module.less';
-
-export default defineComponent({
-  name: 'the-message-dialog',
-  props: {
-    cancelButtonText: {
-      type: String,
-      default: '取消'
-    },
-    confirmButtonText: {
-      type: String,
-      default: '确定'
-    },
-    content: {
-      type: String,
-      default: ''
-    },
-    contentDirection: {
-      type: String as PropType<'left' | 'center' | 'right'>,
-      default: 'center'
-    },
-    loading: {
-      type: Boolean,
-      default: false
-    }
-  },
-  emits: ['close', 'confirm'],
-  setup(props, { emit }) {
-    return () => (
-      <div class={styles.studentRemove}>
-        <p
-          style={{
-            textAlign: props.contentDirection
-          }}
-          v-html={props.content}></p>
-
-        <NSpace class={styles.btnGroupModal} justify="center">
-          <NButton round onClick={() => emit('close')}>
-            {props.cancelButtonText}
-          </NButton>
-          <NButton
-            round
-            type="primary"
-            loading={props.loading}
-            disabled={props.loading}
-            onClick={() => {
-              emit('confirm');
-            }}>
-            {props.confirmButtonText}
-          </NButton>
-        </NSpace>
-      </div>
-    );
-  }
-});
+import { NButton, NSpace } from 'naive-ui';
+import { PropType, defineComponent } from 'vue';
+import styles from './index.module.less';
+
+export default defineComponent({
+  name: 'the-message-dialog',
+  props: {
+    cancelButtonText: {
+      type: String,
+      default: '取消'
+    },
+    confirmButtonText: {
+      type: String,
+      default: '确定'
+    },
+    content: {
+      type: String,
+      default: ''
+    },
+    contentDirection: {
+      type: String as PropType<'left' | 'center' | 'right'>,
+      default: 'center'
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    }
+  },
+  emits: ['close', 'confirm'],
+  setup(props, { emit }) {
+    return () => (
+      <div class={styles.studentRemove}>
+        <p
+          style={{
+            textAlign: props.contentDirection
+          }}
+          v-html={props.content}></p>
+
+        <NSpace class={styles.btnGroupModal} justify="center">
+          <NButton round onClick={() => emit('close')}>
+            {props.cancelButtonText}
+          </NButton>
+          <NButton
+            round
+            type="primary"
+            loading={props.loading}
+            disabled={props.loading}
+            onClick={() => {
+              emit('confirm');
+            }}>
+            {props.confirmButtonText}
+          </NButton>
+        </NSpace>
+      </div>
+    );
+  }
+});

+ 73 - 73
src/components/TheTooltip/index.tsx

@@ -1,73 +1,73 @@
-import { NTooltip } from 'naive-ui';
-import { defineComponent, PropType } from 'vue';
-import styles from './index.module.less';
-
-export default defineComponent({
-  name: 'the-tooltip',
-  props: {
-    maxWidth: {
-      type: Number,
-      default: 300
-    },
-    showContentWidth: {
-      type: Number,
-      default: 120
-    },
-    tipsContent: {
-      type: String,
-      default: ''
-    },
-    content: {
-      type: String,
-      default: ''
-    },
-    placement: {
-      type: String as PropType<
-        | 'top-start'
-        | 'top'
-        | 'top-end'
-        | 'right-start'
-        | 'right'
-        | 'right-end'
-        | 'bottom-start'
-        | 'bottom'
-        | 'bottom-end'
-        | 'left-start'
-        | 'left'
-        | 'left-end'
-      >,
-      default: 'top'
-    },
-    showArrow: {
-      type: Boolean,
-      default: true
-    },
-    trigger: {
-      type: String as PropType<'hover' | 'click'>,
-      default: 'hover'
-    }
-  },
-  setup(props) {
-    return () => (
-      <>
-        <NTooltip
-          style={{ maxWidth: props.maxWidth + 'px' }}
-          trigger={props.trigger}
-          placement={props.placement}
-          showArrow={props.showArrow}
-          delay={500}>
-          {{
-            trigger: () => (
-              <p
-                style={{ maxWidth: props.showContentWidth + 'px' }}
-                class={styles.showContentWidth}>
-                {props.content}
-              </p>
-            ),
-            default: () => props.tipsContent || props.content
-          }}
-        </NTooltip>
-      </>
-    );
-  }
-});
+import { NTooltip } from 'naive-ui';
+import { defineComponent, PropType } from 'vue';
+import styles from './index.module.less';
+
+export default defineComponent({
+  name: 'the-tooltip',
+  props: {
+    maxWidth: {
+      type: Number,
+      default: 300
+    },
+    showContentWidth: {
+      type: Number,
+      default: 120
+    },
+    tipsContent: {
+      type: String,
+      default: ''
+    },
+    content: {
+      type: String,
+      default: ''
+    },
+    placement: {
+      type: String as PropType<
+        | 'top-start'
+        | 'top'
+        | 'top-end'
+        | 'right-start'
+        | 'right'
+        | 'right-end'
+        | 'bottom-start'
+        | 'bottom'
+        | 'bottom-end'
+        | 'left-start'
+        | 'left'
+        | 'left-end'
+      >,
+      default: 'top'
+    },
+    showArrow: {
+      type: Boolean,
+      default: true
+    },
+    trigger: {
+      type: String as PropType<'hover' | 'click'>,
+      default: 'hover'
+    }
+  },
+  setup(props) {
+    return () => (
+      <>
+        <NTooltip
+          style={{ maxWidth: props.maxWidth + 'px' }}
+          trigger={props.trigger}
+          placement={props.placement}
+          showArrow={props.showArrow}
+          delay={500}>
+          {{
+            trigger: () => (
+              <p
+                style={{ maxWidth: props.showContentWidth + 'px' }}
+                class={[styles.showContentWidth, 'showContentWidthWrap']}>
+                {props.content}
+              </p>
+            ),
+            default: () => props.tipsContent || props.content
+          }}
+        </NTooltip>
+      </>
+    );
+  }
+});

+ 466 - 418
src/views/classList/modals/restStudentBox.tsx

@@ -1,418 +1,466 @@
-import {
-  NButton,
-  NSpace,
-  useMessage,
-  NCheckboxGroup,
-  NCheckbox,
-  NRow,
-  NImage,
-  NInput,
-  NScrollbar,
-  NDropdown
-} from 'naive-ui';
-import { computed, defineComponent, onMounted, reactive, ref } from 'vue';
-import styles from '../index.module.less';
-import SearchInput from '@/components/searchInput';
-import smallArrow from '../images/smallArrow.png';
-import transArrrow from '../images/transArrrow.png';
-import transArrowActive from '../images/transArrowActive.png';
-import { getCLassStudent, classGroupList, adjustStudent } from '../api';
-export default defineComponent({
-  props: {
-    activeRow: {
-      type: Object,
-      default: () => ({ id: '' })
-    }
-  },
-  name: 'RestStudentBox',
-  emits: ['close', 'getList'],
-  setup(props, { emit }) {
-    const message = useMessage();
-    const data = reactive({
-      uploading: false
-    });
-    const options = 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({
-      gradeYear: null,
-      name: '',
-      id: ''
-    });
-    const currentchioseStudent = ref([] as any);
-    const currentStudentList = ref([] as any);
-    const currentSearch = ref(null as any);
-
-    const targetchioseStudent = ref([] as any);
-    const targetStudentList = ref([] as any);
-    const targetSearch = ref(null as any);
-    //
-    const submitList = ref([] as any);
-    /**
-     * 这里干3件事  1.获取当前班的学生
-     * 2.查询所有的班级列表  并且排查当前班级
-     * 3.默认选择第一个班级 并且查出此班的学生
-     */
-    const chioseStudnet = (val: any) => {
-      console.log(val);
-    };
-    const getAllClassList = async () => {
-      try {
-        const res = await classGroupList({
-          page: 1,
-          rows: 9999,
-          upgradeFlag: true
-        });
-        classList.value = res.data.rows.map((item: any) => {
-          return {
-            label: item.name,
-            key: item.id,
-            gradeYear: item.gradeYear,
-            disabled: item.id == props.activeRow.id
-          };
-        });
-
-        if (classList.value[0].disabled) {
-          targetClass.name = classList.value[1].label;
-          targetClass.id = classList.value[1].key;
-          targetClass.gradeYear = classList.value[1].gradeYear;
-        } else {
-          targetClass.name = classList.value[0].label;
-          targetClass.id = classList.value[0].key;
-          targetClass.gradeYear = classList.value[0].gradeYear;
-        }
-
-        const tarRes = await getCLassStudentList(targetClass.id);
-        targetStudentList.value = tarRes.data.rows.map((item: any) => {
-          return {
-            label: item.nickname + '(' + item.id + ')',
-            value: item.id
-          };
-        });
-      } 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.gradeYear = item.gradeYear;
-          targetClass.id = item.key;
-        }
-      });
-      const res = await getCLassStudentList(val);
-      targetStudentList.value = res.data.rows.map((item: any) => {
-        return {
-          label: item.nickname + '(' + item.id + ')',
-          value: item.id
-        };
-      });
-      console.log(submitList.value, 'submitList.value');
-      // 判断一下 targetStudentList.value 和 submitList 对比
-      targetStudentList.value = targetStudentList.value.filter(
-        (item: any) =>
-          !submitList.value.some((ele: any) => ele.value === item.value)
-      );
-      // 如果 如果submitList 学生的toClassId 和targetClassId相同 则添加
-      submitList.value.forEach((ele: any) => {
-        if (ele.toClassId == targetClass.id) {
-          console.log(ele.toClassId, ele);
-          targetStudentList.value.push({
-            label: ele.label,
-            value: ele.value
-          });
-        }
-      });
-      // 有2下 如果submitList 学生 和 targetStudentList 学生id相同 则删除
-    };
-    const currentFitterList = computed(() => {
-      const oraginArr = currentStudentList.value || [];
-      const list = oraginArr.filter((item: any) => {
-        return item.label.indexOf(currentSearch.value || '') != -1;
-      });
-      return list;
-    });
-
-    const targetFitterList = computed(() => {
-      const oraginArr = targetStudentList.value || [];
-      const list = oraginArr.filter((item: any) => {
-        return item.label.indexOf(targetSearch.value || '') != -1;
-      });
-      return list;
-    });
-
-    const chioseAllCurrentStudent = () => {
-      if (
-        currentFitterList.value.length === currentchioseStudent.value.length
-      ) {
-        // 说明要取消全选
-        currentchioseStudent.value = [];
-      } else {
-        currentchioseStudent.value = currentFitterList.value.map(
-          (item: any) => {
-            return item.value;
-          }
-        );
-        // 全选
-      }
-    };
-
-    const chioseAllTargetStudent = () => {
-      if (targetFitterList.value.length === targetchioseStudent.value.length) {
-        // 说明要取消全选
-        targetchioseStudent.value = [];
-      } else {
-        targetchioseStudent.value = targetFitterList.value.map((item: any) => {
-          return item.value;
-        });
-        // 全选
-      }
-    };
-    const toTargetList = () => {
-      const subStudetn = currentStudentList.value.filter((item: any) => {
-        return currentchioseStudent.value.indexOf(item.value) != -1;
-      });
-      if (subStudetn.length > 0) {
-        const arr = subStudetn.map((item: any) => {
-          return {
-            ...item,
-            studentId: item.value,
-            toClassId: targetClass.id
-          };
-        });
-        submitList.value = submitList.value.filter(
-          (item: any) => !arr.some((ele: any) => ele.value === item.value)
-        );
-        submitList.value = submitList.value.concat(arr);
-      }
-      // 接下来 删除 currentStudentList里的这三个学生
-      currentStudentList.value = currentStudentList.value.filter(
-        (item: any) => !subStudetn.some((ele: any) => ele.value === item.value)
-      );
-      subStudetn.forEach((item: any) => {
-        targetStudentList.value.push(item);
-      });
-      currentchioseStudent.value = [];
-    };
-    const toCurrentList = () => {
-      const subStudetn = targetStudentList.value.filter((item: any) => {
-        return targetchioseStudent.value.indexOf(item.value) != -1;
-      });
-      if (subStudetn.length > 0) {
-        const arr = subStudetn.map((item: any) => {
-          return {
-            ...item,
-            studentId: item.value,
-            toClassId: props.activeRow.id
-          };
-        });
-        submitList.value = submitList.value.filter(
-          (item: any) => !arr.some((ele: any) => ele.value === item.value)
-        );
-        submitList.value = submitList.value.concat(arr);
-      }
-      targetStudentList.value = targetStudentList.value.filter(
-        (item: any) => !subStudetn.some((ele: any) => ele.value === item.value)
-      );
-      subStudetn.forEach((item: any) => {
-        currentStudentList.value.push(item);
-      });
-      targetchioseStudent.value = [];
-      // 过去 所以
-      console.log(submitList.value, ' submitList.value===>');
-    };
-
-    const submitStudent = async () => {
-      if (classList.value.length < 2) {
-        message.error('当前只有一个班级,无法调整');
-        return;
-      }
-      if (submitList.value < 1) {
-        emit('close');
-        return;
-      }
-      try {
-        const res = await adjustStudent(submitList.value);
-        emit('close');
-        emit('getList');
-      } catch (e) {
-        console.log(e);
-      }
-    };
-    onMounted(async () => {
-      getAllClassList();
-      const res = await getCLassStudentList(props.activeRow.id as string);
-      currentStudentList.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}>
-          <div class={styles.studentTransferList}>
-            <div class={styles.studentLeft}>
-              <div class={styles.listTop}>
-                <p>{props.activeRow.name}</p>
-                <span>(当前班级)</span>
-              </div>
-              <div class={styles.listCore}>
-                <NRow class={styles.chioseCheckAllBox}>
-                  <NCheckbox
-                    onUpdateChecked={val => {
-                      chioseAllCurrentStudent();
-                    }}
-                    checked={
-                      currentFitterList.value.length ===
-                      currentchioseStudent.value.length
-                    }
-                    indeterminate={
-                      currentchioseStudent.value.length > 0 &&
-                      currentFitterList.value.length !==
-                        currentchioseStudent.value.length
-                    }
-                    label="全选"></NCheckbox>
-                </NRow>
-                <NRow>
-                  <SearchInput
-                    {...{ placeholder: '请输入学生姓名' }}
-                    class={styles.searchInput}
-                    searchWord={currentSearch.value}
-                    onChangeValue={(val: string) =>
-                      (currentSearch.value = val)
-                    }></SearchInput>
-                </NRow>
-                <NScrollbar style="max-height: 204px;min-height: 204px;margin-top:14px;">
-                  <NCheckboxGroup v-model:value={currentchioseStudent.value}>
-                    {currentFitterList.value.map((item: any) => (
-                      <NRow class={styles.chioseCheckBox}>
-                        <NCheckbox
-                          value={item.value}
-                          label={item.label}></NCheckbox>
-                      </NRow>
-                    ))}
-                  </NCheckboxGroup>
-                </NScrollbar>
-              </div>
-              <div class={[styles.bottomLeft, styles.bottom]}>
-                <div class={styles.bottomWrap}>
-                  共{currentStudentList.value.length}名学生
-                </div>
-              </div>
-            </div>
-            <div class={styles.chioseBox}>
-              <div
-                class={[styles.chioseBtn, styles.chioseBtnRight]}
-                onClick={() => toTargetList()}></div>
-              <div
-                class={styles.chioseBtn}
-                onClick={() => toCurrentList()}></div>
-            </div>
-            <div class={styles.studentRight}>
-              <div class={styles.listTop}>
-                {targetClass.id ? (
-                  <NDropdown
-                    key="111"
-                    v-model:value={targetClass.id}
-                    options={classList.value}
-                    onSelect={(value: any) => {
-                      chioseClass(value);
-                    }}
-                    scrollable>
-                    <div class={styles.showGradeSection}>
-                      <div>
-                        {targetClass.name}
-                        {targetClass.gradeYear && (
-                          <span>({targetClass.gradeYear}学年)</span>
-                        )}
-                      </div>
-                      {/* gradeYear */}
-                      <NImage
-                        class={styles.smallArrow}
-                        src={smallArrow}
-                        previewDisabled></NImage>
-                    </div>
-                  </NDropdown>
-                ) : null}
-              </div>
-              <div class={styles.listCore}>
-                <NRow class={styles.chioseCheckAllBox}>
-                  <NCheckbox
-                    onUpdateChecked={val => {
-                      chioseAllTargetStudent();
-                    }}
-                    checked={
-                      targetFitterList.value.length ===
-                      targetchioseStudent.value.length
-                    }
-                    indeterminate={
-                      targetchioseStudent.value.length > 0 &&
-                      targetFitterList.value.length !==
-                        targetchioseStudent.value.length
-                    }
-                    label="全选"></NCheckbox>
-                </NRow>
-                <NRow>
-                  <SearchInput
-                    {...{ placeholder: '请输入学生姓名' }}
-                    class={styles.searchInput}
-                    searchWord={targetSearch.value}
-                    onChangeValue={(val: string) =>
-                      (targetSearch.value = val)
-                    }></SearchInput>
-                </NRow>
-                <NScrollbar style="max-height: 204px;min-height: 204px;margin-top:14px;">
-                  <NCheckboxGroup v-model:value={targetchioseStudent.value}>
-                    {targetFitterList.value.map((item: any) => (
-                      <NRow class={styles.chioseCheckBox}>
-                        <NCheckbox
-                          value={item.value}
-                          label={item.label}></NCheckbox>
-                      </NRow>
-                    ))}
-                  </NCheckboxGroup>
-                </NScrollbar>
-              </div>
-              <div class={[styles.bottomRight, styles.bottom]}>
-                <div class={styles.bottomWrap}>
-                  共{targetStudentList.value.length}名学生
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-
-        <NSpace class={styles.btnGroup} justify="center">
-          <NButton round onClick={() => emit('close')}>
-            取消
-          </NButton>
-          <NButton
-            round
-            loading={data.uploading}
-            type="primary"
-            onClick={() => {
-              submitStudent();
-            }}>
-            保存
-          </NButton>
-        </NSpace>
-      </div>
-    );
-  }
-});
+import {
+  NButton,
+  NSpace,
+  useMessage,
+  NCheckboxGroup,
+  NCheckbox,
+  NRow,
+  NImage,
+  NInput,
+  NScrollbar,
+  NDropdown
+} from 'naive-ui';
+import { computed, defineComponent, onMounted, reactive, ref } from 'vue';
+import styles from '../index.module.less';
+import SearchInput from '@/components/searchInput';
+import smallArrow from '../images/smallArrow.png';
+import transArrrow from '../images/transArrrow.png';
+import transArrowActive from '../images/transArrowActive.png';
+import { getCLassStudent, classGroupList, adjustStudent } from '../api';
+export default defineComponent({
+  props: {
+    activeRow: {
+      type: Object,
+      default: () => ({ id: '' })
+    }
+  },
+  name: 'RestStudentBox',
+  emits: ['close', 'getList'],
+  setup(props, { emit }) {
+    const message = useMessage();
+    const data = reactive({
+      uploading: false
+    });
+    const options = 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({
+      gradeYear: null,
+      name: '',
+      id: ''
+    });
+    const currentchioseStudent = ref([] as any);
+    const currentStudentList = ref([] as any);
+    const currentSearch = ref(null as any);
+
+    const targetchioseStudent = ref([] as any);
+    const targetStudentList = ref([] as any);
+    const targetSearch = ref(null as any);
+    //
+    const submitList = ref([] as any);
+    /**
+     * 这里干3件事  1.获取当前班的学生
+     * 2.查询所有的班级列表  并且排查当前班级
+     * 3.默认选择第一个班级 并且查出此班的学生
+     */
+    const chioseStudnet = (val: any) => {
+      console.log(val);
+    };
+    const getAllClassList = async () => {
+      try {
+        const res = await classGroupList({
+          page: 1,
+          rows: 9999,
+          upgradeFlag: true
+        });
+        // classList.value = res.data.rows.map((item: any) => {
+        //   return {
+        //     label: item.name,
+        //     key: item.id,
+        //     gradeYear: item.gradeYear,
+        //     disabled: item.id == props.activeRow.id
+        //   };
+        // });
+
+        // if (classList.value[0].disabled) {
+        //   targetClass.name = classList.value[1].label;
+        //   targetClass.id = classList.value[1].key;
+        //   targetClass.gradeYear = classList.value[1].gradeYear;
+        // } else {
+        //   targetClass.name = classList.value[0].label;
+        //   targetClass.id = classList.value[0].key;
+        //   targetClass.gradeYear = classList.value[0].gradeYear;
+        // }
+
+        // const tarRes = await getCLassStudentList(targetClass.id);
+        // targetStudentList.value = tarRes.data.rows.map((item: any) => {
+        //   return {
+        //     label: item.nickname + '(' + item.id + ')',
+        //     value: item.id
+        //   };
+        // });
+        const result = res.data.rows || [];
+        const currentYearList: any = [];
+        const otherYearList: any = [];
+        result.forEach((item: any) => {
+          const params = {
+            label: item.name,
+            key: item.id,
+            gradeYear: item.gradeYear,
+            value: item.id,
+            disabled: item.id == props.activeRow.id
+          };
+          if (props.activeRow.gradeYear === item.gradeYear) {
+            currentYearList.push(params);
+          } else {
+            otherYearList.push(params);
+          }
+        });
+
+        classList.value = [...currentYearList, ...otherYearList];
+
+        if (classList.value[0].disabled) {
+          if (classList.value.length > 1) {
+            targetClass.name = classList.value[1].label;
+            targetClass.id = classList.value[1].key;
+            targetClass.gradeYear = classList.value[1].gradeYear;
+          }
+        } else {
+          targetClass.name = classList.value[0].label;
+          targetClass.id = classList.value[0].key;
+          targetClass.gradeYear = classList.value[0].gradeYear;
+        }
+        if (targetClass.id) {
+          const tarRes = await getCLassStudentList(targetClass.id);
+          targetStudentList.value = tarRes.data.rows.map((item: any) => {
+            return {
+              label: item.nickname + '(' + item.id + ')',
+              value: item.id
+            };
+          });
+        }
+      } 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.gradeYear = item.gradeYear;
+          targetClass.id = item.key;
+        }
+      });
+      const res = await getCLassStudentList(val);
+      targetStudentList.value = res.data.rows.map((item: any) => {
+        return {
+          label: item.nickname + '(' + item.id + ')',
+          value: item.id
+        };
+      });
+      console.log(submitList.value, 'submitList.value');
+      // 判断一下 targetStudentList.value 和 submitList 对比
+      targetStudentList.value = targetStudentList.value.filter(
+        (item: any) =>
+          !submitList.value.some((ele: any) => ele.value === item.value)
+      );
+      // 如果 如果submitList 学生的toClassId 和targetClassId相同 则添加
+      submitList.value.forEach((ele: any) => {
+        if (ele.toClassId == targetClass.id) {
+          console.log(ele.toClassId, ele);
+          targetStudentList.value.push({
+            label: ele.label,
+            value: ele.value
+          });
+        }
+      });
+      // 有2下 如果submitList 学生 和 targetStudentList 学生id相同 则删除
+    };
+    const currentFitterList = computed(() => {
+      const oraginArr = currentStudentList.value || [];
+      const list = oraginArr.filter((item: any) => {
+        return item.label.indexOf(currentSearch.value || '') != -1;
+      });
+      return list;
+    });
+
+    const targetFitterList = computed(() => {
+      const oraginArr = targetStudentList.value || [];
+      const list = oraginArr.filter((item: any) => {
+        return item.label.indexOf(targetSearch.value || '') != -1;
+      });
+      return list;
+    });
+
+    const chioseAllCurrentStudent = () => {
+      if (
+        currentFitterList.value.length === currentchioseStudent.value.length
+      ) {
+        // 说明要取消全选
+        currentchioseStudent.value = [];
+      } else {
+        currentchioseStudent.value = currentFitterList.value.map(
+          (item: any) => {
+            return item.value;
+          }
+        );
+        // 全选
+      }
+    };
+
+    const chioseAllTargetStudent = () => {
+      if (targetFitterList.value.length === targetchioseStudent.value.length) {
+        // 说明要取消全选
+        targetchioseStudent.value = [];
+      } else {
+        targetchioseStudent.value = targetFitterList.value.map((item: any) => {
+          return item.value;
+        });
+        // 全选
+      }
+    };
+    const toTargetList = () => {
+      const subStudetn = currentStudentList.value.filter((item: any) => {
+        return currentchioseStudent.value.indexOf(item.value) != -1;
+      });
+      if (subStudetn.length > 0) {
+        const arr = subStudetn.map((item: any) => {
+          return {
+            ...item,
+            studentId: item.value,
+            toClassId: targetClass.id
+          };
+        });
+        submitList.value = submitList.value.filter(
+          (item: any) => !arr.some((ele: any) => ele.value === item.value)
+        );
+        submitList.value = submitList.value.concat(arr);
+      }
+      // 接下来 删除 currentStudentList里的这三个学生
+      currentStudentList.value = currentStudentList.value.filter(
+        (item: any) => !subStudetn.some((ele: any) => ele.value === item.value)
+      );
+      subStudetn.forEach((item: any) => {
+        targetStudentList.value.push(item);
+      });
+      currentchioseStudent.value = [];
+    };
+    const toCurrentList = () => {
+      const subStudetn = targetStudentList.value.filter((item: any) => {
+        return targetchioseStudent.value.indexOf(item.value) != -1;
+      });
+      if (subStudetn.length > 0) {
+        const arr = subStudetn.map((item: any) => {
+          return {
+            ...item,
+            studentId: item.value,
+            toClassId: props.activeRow.id
+          };
+        });
+        submitList.value = submitList.value.filter(
+          (item: any) => !arr.some((ele: any) => ele.value === item.value)
+        );
+        submitList.value = submitList.value.concat(arr);
+      }
+      targetStudentList.value = targetStudentList.value.filter(
+        (item: any) => !subStudetn.some((ele: any) => ele.value === item.value)
+      );
+      subStudetn.forEach((item: any) => {
+        currentStudentList.value.push(item);
+      });
+      targetchioseStudent.value = [];
+      // 过去 所以
+      console.log(submitList.value, ' submitList.value===>');
+    };
+
+    const submitStudent = async () => {
+      if (classList.value.length < 2) {
+        message.error('当前只有一个班级,无法调整');
+        return;
+      }
+      if (submitList.value < 1) {
+        emit('close');
+        return;
+      }
+      try {
+        const res = await adjustStudent(submitList.value);
+        emit('close');
+        emit('getList');
+      } catch (e) {
+        console.log(e);
+      }
+    };
+    onMounted(async () => {
+      getAllClassList();
+      const res = await getCLassStudentList(props.activeRow.id as string);
+      currentStudentList.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}>
+          <div class={styles.studentTransferList}>
+            <div class={styles.studentLeft}>
+              <div class={styles.listTop}>
+                <p>{props.activeRow.name}</p>
+                <span>({props.activeRow.gradeYear}学年)</span>
+              </div>
+              <div class={styles.listCore}>
+                <NRow class={styles.chioseCheckAllBox}>
+                  <NCheckbox
+                    onUpdateChecked={val => {
+                      chioseAllCurrentStudent();
+                    }}
+                    checked={
+                      currentFitterList.value.length ===
+                      currentchioseStudent.value.length
+                    }
+                    indeterminate={
+                      currentchioseStudent.value.length > 0 &&
+                      currentFitterList.value.length !==
+                        currentchioseStudent.value.length
+                    }
+                    label="全选"></NCheckbox>
+                </NRow>
+                <NRow>
+                  <SearchInput
+                    {...{ placeholder: '请输入学生姓名' }}
+                    class={styles.searchInput}
+                    searchWord={currentSearch.value}
+                    onChangeValue={(val: string) =>
+                      (currentSearch.value = val)
+                    }></SearchInput>
+                </NRow>
+                <NScrollbar style="max-height: 204px;min-height: 204px;margin-top:14px;">
+                  <NCheckboxGroup v-model:value={currentchioseStudent.value}>
+                    {currentFitterList.value.map((item: any) => (
+                      <NRow class={styles.chioseCheckBox}>
+                        <NCheckbox
+                          value={item.value}
+                          label={item.label}></NCheckbox>
+                      </NRow>
+                    ))}
+                  </NCheckboxGroup>
+                </NScrollbar>
+              </div>
+              <div class={[styles.bottomLeft, styles.bottom]}>
+                <div class={styles.bottomWrap}>
+                  共{currentStudentList.value.length}名学生
+                </div>
+              </div>
+            </div>
+            <div class={styles.chioseBox}>
+              <div
+                class={[styles.chioseBtn, styles.chioseBtnRight]}
+                onClick={() => toTargetList()}></div>
+              <div
+                class={styles.chioseBtn}
+                onClick={() => toCurrentList()}></div>
+            </div>
+            <div class={styles.studentRight}>
+              <div class={styles.listTop}>
+                {targetClass.id ? (
+                  <NDropdown
+                    key="111"
+                    v-model:value={targetClass.id}
+                    options={classList.value}
+                    onSelect={(value: any) => {
+                      chioseClass(value);
+                    }}
+                    renderLabel={(option: any) => (
+                      <div style={{ display: 'flex' }}>
+                        {option.label}
+                        <div style={{ fontSize: '12Px' }}>
+                          ({option.gradeYear}学年)
+                        </div>
+                      </div>
+                    )}
+                    scrollable>
+                    <div class={styles.showGradeSection}>
+                      <div>
+                        {targetClass.name}
+                        {targetClass.gradeYear && (
+                          <span>({targetClass.gradeYear}学年)</span>
+                        )}
+                      </div>
+                      {/* gradeYear */}
+                      <NImage
+                        class={styles.smallArrow}
+                        src={smallArrow}
+                        previewDisabled></NImage>
+                    </div>
+                  </NDropdown>
+                ) : null}
+              </div>
+              <div class={styles.listCore}>
+                <NRow class={styles.chioseCheckAllBox}>
+                  <NCheckbox
+                    onUpdateChecked={val => {
+                      chioseAllTargetStudent();
+                    }}
+                    checked={
+                      targetFitterList.value.length ===
+                      targetchioseStudent.value.length
+                    }
+                    indeterminate={
+                      targetchioseStudent.value.length > 0 &&
+                      targetFitterList.value.length !==
+                        targetchioseStudent.value.length
+                    }
+                    label="全选"></NCheckbox>
+                </NRow>
+                <NRow>
+                  <SearchInput
+                    {...{ placeholder: '请输入学生姓名' }}
+                    class={styles.searchInput}
+                    searchWord={targetSearch.value}
+                    onChangeValue={(val: string) =>
+                      (targetSearch.value = val)
+                    }></SearchInput>
+                </NRow>
+                <NScrollbar style="max-height: 204px;min-height: 204px;margin-top:14px;">
+                  <NCheckboxGroup v-model:value={targetchioseStudent.value}>
+                    {targetFitterList.value.map((item: any) => (
+                      <NRow class={styles.chioseCheckBox}>
+                        <NCheckbox
+                          value={item.value}
+                          label={item.label}></NCheckbox>
+                      </NRow>
+                    ))}
+                  </NCheckboxGroup>
+                </NScrollbar>
+              </div>
+              <div class={[styles.bottomRight, styles.bottom]}>
+                <div class={styles.bottomWrap}>
+                  共{targetStudentList.value.length}名学生
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <NSpace class={styles.btnGroup} justify="center">
+          <NButton round onClick={() => emit('close')}>
+            取消
+          </NButton>
+          <NButton
+            round
+            loading={data.uploading}
+            type="primary"
+            onClick={() => {
+              submitStudent();
+            }}>
+            保存
+          </NButton>
+        </NSpace>
+      </div>
+    );
+  }
+});

+ 250 - 239
src/views/homework-record/detail/index.module.less

@@ -1,240 +1,251 @@
-.listWrap {
-  // min-height: 100%;
-  padding: 32px;
-  background-color: #fff;
-  border-radius: 20px;
-  min-height: calc(100vh - 7.8125vw) !important
-}
-
-.teacherSection {
-  display: flex;
-  align-items: center;
-  border-bottom: 1px solid #E9E9E9;
-  margin-bottom: 30px;
-  padding-bottom: 24px;
-
-  .tTemp {
-    display: flex;
-    align-content: center;
-  }
-
-  .infos {
-    margin-top: 8px;
-    padding: 13px;
-    background: #FFFFFF;
-    border-radius: 10px;
-
-    .homeTitle {
-      font-size: max(17px, 14Px);
-      font-family: PingFangSC, PingFang SC;
-      font-weight: 600;
-      color: #000000;
-      padding-bottom: 8px;
-    }
-
-    .homeContent {
-      padding-bottom: 5px;
-    }
-
-    .homeworkText {
-      display: flex;
-      align-items: flex-start;
-
-      .pSection {
-        max-width: 500px;
-      }
-
-      .p1,
-      .p2 {
-        white-space: nowrap;
-        overflow: hidden;
-        text-overflow: ellipsis;
-
-
-      }
-
-      .p1::before,
-      .p2::before {
-        content: '';
-        display: inline-block;
-        width: 5px;
-        height: 5px;
-        background: #198CFE;
-        margin-right: 7px;
-        border-radius: 50%;
-        flex-shrink: 0;
-        transform: translateY(-3px);
-      }
-
-      .p2 {
-        padding-top: 6px;
-      }
-
-      .p2::before {
-        background: #F44040;
-      }
-    }
-
-    .title {
-      font-size: max(13px, 12Px);
-      color: #777777;
-      flex-shrink: 0;
-    }
-
-    .text {
-      font-size: max(13px, 12Px);
-      font-weight: 500;
-      color: #333333;
-      line-height: 22px;
-    }
-
-  }
-
-  .stitcTitle {
-    display: flex;
-    align-items: center;
-    font-size: max(20px, 16Px);
-    font-family: PingFangSC, PingFang SC;
-    font-weight: 600;
-    color: #000000;
-    line-height: 28px;
-    padding-bottom: 30px;
-
-    &::before {
-      content: '';
-      display: inline-block;
-      width: 4px;
-      height: 14px;
-      background: #198CFE;
-      border-radius: 2px;
-      margin-right: 8px;
-    }
-  }
-
-  .stitcConent {
-    :global {
-      .n-progress {
-        width: 116Px;
-      }
-    }
-
-    .contentRect {
-      text-align: center;
-
-      .text {
-        padding-top: 5px;
-        font-size: 12Px;
-        font-family: PingFangSC, PingFang SC;
-        font-weight: 400;
-        color: #777777;
-        line-height: 17px;
-      }
-    }
-
-    .nums {
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      font-size: max(26px, 18Px);
-      font-family: DINAlternate, DINAlternate;
-      font-weight: bold;
-      color: #000000;
-      line-height: 30px;
-
-      i {
-        font-style: normal;
-        font-size: max(20px, 14Px);
-      }
-
-      span {
-        font-size: 12Px;
-        font-family: PingFangSC, PingFang SC;
-        font-weight: 500;
-        color: #333333;
-        line-height: 17px;
-      }
-    }
-  }
-}
-
-.teacherList {
-  display: flex;
-  // align-items: center;
-  flex-direction: column;
-  // margin-bottom: 32px;
-  flex: 1;
-  margin-right: 60px;
-  position: relative;
-
-  &::after {
-    content: '';
-    position: absolute;
-    right: 0;
-    width: 1px;
-    height: 120px;
-    background: #E9E9E9;
-    top: 50%;
-    margin-top: -60px;
-  }
-
-
-
-  .teacherHeader {
-    width: 100px;
-    height: 100px;
-    padding: 4px;
-    border-radius: 99px;
-    background: linear-gradient(228deg,
-        rgba(2, 186, 255, 1),
-        rgba(0, 122, 254, 1));
-    margin-right: 20px;
-
-    .teacherHeaderBorder {
-      width: 100%;
-      height: 100%;
-      background: #fff;
-      border-radius: 99px;
-      overflow: hidden;
-      display: flex;
-      flex-direction: row;
-      align-items: center;
-      justify-content: center;
-      padding: 4px;
-    }
-  }
-
-  .teacherHeaderImg {
-    width: 84px;
-    height: 84px;
-    border-radius: 50%;
-    overflow: hidden;
-  }
-
-  .workafterInfo {
-    display: flex;
-    justify-content: center;
-    flex-direction: column;
-
-    h4 {
-      font-size: 22px;
-      line-height: 30px;
-      font-weight: 600;
-      color: #131415;
-      margin-bottom: 12px;
-    }
-
-    p {
-      font-size: max(16px, 12Px);
-      line-height: 22px;
-      color: #777;
-
-      span {
-        color: #ea4132;
-      }
-    }
-  }
-}
-
-.wordDetailModel {
-  width: 1012px;
+.listWrap {
+  // min-height: 100%;
+  padding: 32px;
+  background-color: #fff;
+  border-radius: 20px;
+  min-height: calc(100vh - 7.8125vw) !important
+}
+
+.teacherSection {
+  display: flex;
+  align-items: center;
+  border-bottom: 1px solid #E9E9E9;
+  margin-bottom: 30px;
+  padding-bottom: 24px;
+
+  .tTemp {
+    display: flex;
+    align-content: center;
+  }
+
+  .infos {
+    margin-top: 8px;
+    padding: 13px;
+    background: #FFFFFF;
+    border-radius: 10px;
+
+    .homeTitle {
+      font-size: max(17px, 14Px);
+      font-family: PingFangSC, PingFang SC;
+      font-weight: 600;
+      color: #000000;
+      padding-bottom: 8px;
+    }
+
+    .homeContent {
+      padding-bottom: 5px;
+    }
+
+    .homeworkText {
+      display: flex;
+      align-items: flex-start;
+
+      .pSection {
+        max-width: 790px;
+      }
+
+      .p1,
+      .p2 {
+        // white-space: nowrap;
+        // overflow: hidden;
+        // text-overflow: ellipsis;
+
+        &>div {
+          display: flex;
+          align-items: flex-start;
+          color: #838383;
+
+          span {
+            color: #313131;
+            flex-shrink: 0;
+          }
+        }
+      }
+
+      .p1::before,
+      .p2::before {
+        content: '';
+        display: inline-block;
+        width: 5px;
+        height: 5px;
+        background: #198CFE;
+        margin-right: 7px;
+        border-radius: 50%;
+        flex-shrink: 0;
+        transform: translateY(-3px);
+      }
+
+      .p2 {
+        padding-top: 6px;
+      }
+
+      .p2::before {
+        background: #F44040;
+      }
+    }
+
+    .title {
+      font-size: max(13px, 12Px);
+      color: #777777;
+      flex-shrink: 0;
+    }
+
+    .text {
+      font-size: max(13px, 12Px);
+      font-weight: 500;
+      color: #333333;
+      line-height: 22px;
+      display: flex;
+      align-items: baseline;
+    }
+
+  }
+
+  .stitcTitle {
+    display: flex;
+    align-items: center;
+    font-size: max(20px, 16Px);
+    font-family: PingFangSC, PingFang SC;
+    font-weight: 600;
+    color: #000000;
+    line-height: 28px;
+    padding-bottom: 30px;
+
+    &::before {
+      content: '';
+      display: inline-block;
+      width: 4px;
+      height: 14px;
+      background: #198CFE;
+      border-radius: 2px;
+      margin-right: 8px;
+    }
+  }
+
+  .stitcConent {
+    :global {
+      .n-progress {
+        width: 116Px;
+      }
+    }
+
+    .contentRect {
+      text-align: center;
+
+      .text {
+        padding-top: 5px;
+        font-size: 12Px;
+        font-family: PingFangSC, PingFang SC;
+        font-weight: 400;
+        color: #777777;
+        line-height: 17px;
+      }
+    }
+
+    .nums {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-size: max(26px, 18Px);
+      font-family: DINAlternate, DINAlternate;
+      font-weight: bold;
+      color: #000000;
+      line-height: 30px;
+
+      i {
+        font-style: normal;
+        font-size: max(20px, 14Px);
+      }
+
+      span {
+        font-size: 12Px;
+        font-family: PingFangSC, PingFang SC;
+        font-weight: 500;
+        color: #333333;
+        line-height: 17px;
+      }
+    }
+  }
+}
+
+.teacherList {
+  display: flex;
+  // align-items: center;
+  flex-direction: column;
+  // margin-bottom: 32px;
+  flex: 1;
+  margin-right: 60px;
+  position: relative;
+
+  &::after {
+    content: '';
+    position: absolute;
+    right: 0;
+    width: 1px;
+    height: 55%;
+    background: #E9E9E9;
+    top: 50%;
+    margin-top: -60px;
+  }
+
+
+
+  .teacherHeader {
+    width: 100px;
+    height: 100px;
+    padding: 4px;
+    border-radius: 99px;
+    background: linear-gradient(228deg,
+        rgba(2, 186, 255, 1),
+        rgba(0, 122, 254, 1));
+    margin-right: 20px;
+
+    .teacherHeaderBorder {
+      width: 100%;
+      height: 100%;
+      background: #fff;
+      border-radius: 99px;
+      overflow: hidden;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      justify-content: center;
+      padding: 4px;
+    }
+  }
+
+  .teacherHeaderImg {
+    width: 84px;
+    height: 84px;
+    border-radius: 50%;
+    overflow: hidden;
+  }
+
+  .workafterInfo {
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
+
+    h4 {
+      font-size: 22px;
+      line-height: 30px;
+      font-weight: 600;
+      color: #131415;
+      margin-bottom: 12px;
+    }
+
+    p {
+      font-size: max(16px, 12Px);
+      line-height: 22px;
+      color: #777;
+
+      span {
+        color: #ea4132;
+      }
+    }
+  }
+}
+
+.wordDetailModel {
+  width: 1012px;
 }

+ 58 - 9
src/views/homework-record/detail/index.tsx

@@ -21,6 +21,7 @@ import { trainingStatusArray } from '@/utils/searchArray';
 import dayjs from 'dayjs';
 import TheEmpty from '/src/components/TheEmpty';
 import TrainingDetails from '../../classList/modals/TrainingDetails';
+import { evaluateDifficult } from '/src/utils/contants';
 export default defineComponent({
   name: 'homewrok-record-detail',
   setup() {
@@ -28,6 +29,7 @@ export default defineComponent({
     const state = reactive({
       searchForm: {
         keyword: '',
+        vipFlag: null as any,
         trainingStatus: '' as any,
         classGroupId: '' as any
       },
@@ -58,6 +60,7 @@ export default defineComponent({
     const onReset = () => {
       state.searchForm = {
         keyword: '',
+        vipFlag: null,
         trainingStatus: '' as any,
         classGroupId: '' as any
       };
@@ -106,16 +109,35 @@ export default defineComponent({
             // if (child.trainingType === 'EVALUATION' && child.musicName) {
             //   eTitle += eTitle ? '、' + child.musicName : child.musicName;
             // }
+            const trainingContent = child.trainingContent
+              ? JSON.parse(child.trainingContent)
+              : null;
 
             if (child.trainingType === 'PRACTICE' && child.musicName) {
-              pTitle += pTitle
-                ? '、《' + child.musicName + '》'
-                : '练习曲目《' + child.musicName + '》';
+              pTitle += '《' + child.musicName + '》';
+
+              if (trainingContent) {
+                const tempList = [
+                  `${trainingContent.practiceChapterBegin}-${trainingContent.practiceChapterEnd}小节`,
+                  `速度${trainingContent.practiceSpeed}`,
+                  `${trainingContent.trainingTimes}分钟`
+                ];
+                pTitle += tempList.join(' | ') + ';';
+              }
             }
             if (child.trainingType === 'EVALUATION' && child.musicName) {
-              eTitle += eTitle
-                ? '、《' + child.musicName + '》'
-                : '评测曲目《' + child.musicName + '》';
+              eTitle += '《' + child.musicName + '》';
+              if (trainingContent) {
+                const tempList = [
+                  `${evaluateDifficult[trainingContent.evaluateDifficult]}`,
+                  trainingContent.practiceChapterBegin ||
+                  trainingContent.practiceChapterEnd
+                    ? `${trainingContent.practiceChapterBegin}-${trainingContent.practiceChapterEnd}小节`
+                    : '全部小节',
+                  `${trainingContent.trainingTimes}分合格`
+                ];
+                eTitle += tempList.join(' | ') + ';';
+              }
             }
           });
         }
@@ -167,7 +189,7 @@ export default defineComponent({
         },
         {
           title: '作业状态',
-          key: 'sex',
+          key: 'trainingStatus',
           render(row: any) {
             return (
               <div>
@@ -185,6 +207,13 @@ export default defineComponent({
           }
         },
         {
+          title: '是否会员',
+          key: 'vipFlag',
+          render(row: any) {
+            return row.vipFlag ? '是' : '否';
+          }
+        },
+        {
           title: '操作',
           key: 'id',
           render(row: any, index: number) {
@@ -272,12 +301,18 @@ export default defineComponent({
                   <div class={styles.pSection}>
                     {state.workInfo.pTitle && (
                       <p class={[styles.text, styles.p1]}>
-                        {state.workInfo.pTitle}
+                        <div>
+                          <span>练习曲目:</span>
+                          <p>{state.workInfo.pTitle}</p>
+                        </div>
                       </p>
                     )}
                     {state.workInfo.eTitle && (
                       <p class={[styles.text, styles.p2]}>
-                        {state.workInfo.eTitle}
+                        <div>
+                          <span>评测曲目:</span>
+                          <p>{state.workInfo.eTitle}</p>
+                        </div>
                       </p>
                     )}
                   </div>
@@ -399,6 +434,20 @@ export default defineComponent({
               </NFormItem>
 
               <NFormItem>
+                <CSelect
+                  {...({
+                    options: [
+                      { label: '是', value: true },
+                      { label: '否', value: false }
+                    ],
+                    placeholder: '是否会员',
+                    clearable: true,
+                    inline: true
+                  } as any)}
+                  v-model:value={state.searchForm.vipFlag}></CSelect>
+              </NFormItem>
+
+              <NFormItem>
                 <NSpace justify="end">
                   <NButton type="primary" class="searchBtn" onClick={search}>
                     搜索

+ 360 - 349
src/views/homework-record/index.module.less

@@ -1,350 +1,361 @@
-.listWrap {
-  padding: 32px;
-  background-color: #fff;
-  border-radius: 20px;
-}
-
-.searchList {
-  .searchInput {
-    max-width: 260px;
-  }
-
-  // .CDatePickerItem {
-  //   :global {
-  //     .n-input {
-  //       width: 303px;
-  //     }
-  //   }
-  // }
-
-  :global {
-    .n-form.n-form--inline {
-      flex-wrap: wrap;
-    }
-
-    .n-form.n-form--inline .n-form-item {
-      margin-right: 18px;
-    }
-
-    // .n-form-item-blank>div {
-    //   .n-select {
-    //     min-width: 150px !important;
-    //     width: 150px !important;
-    //   }
-    // }
-  }
-}
-
-.infoListWrap {
-  min-height: calc(100vh - 150px) !important
-}
-
-.addBtnIcon {
-  width: 13Px !important;
-  height: 14Px !important;
-}
-
-.addBtn {
-  margin-bottom: 30px;
-  background: #198cfe !important;
-  border-radius: 7Px !important;
-  padding: 0 18Px !important;
-  font-weight: 600 !important;
-}
-
-.btnGroup {
-  padding: 40px 0;
-
-  :global {
-    .n-button {
-      height: 47px;
-      min-width: 156px;
-    }
-  }
-}
-
-.addClass {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  padding-top: 50px;
-}
-
-.listWrap {
-  min-height: 100%;
-  padding: 32px;
-  background-color: #fff;
-  border-radius: 20px;
-
-}
-
-.workVisiable {
-  width: 1258px;
-}
-
-.workContainer {
-  display: flex;
-  align-items: center;
-
-  .workTrain {
-    flex: 1;
-    height: 75vh;
-
-    &>div {
-      padding-top: 15px;
-    }
-  }
-
-  :global {
-    .train-container {
-      // max-height: calc(var(--window-page-lesson-height) - 135px) !important;
-      max-height: calc(var(--window-page-lesson-height) - 100px) !important;
-
-      .train-listSection {
-        min-height: calc(var(--window-page-lesson-height) - 100px) !important;
-      }
-    }
-  }
-
-  .resourceMain {
-    flex: 0 0 360px;
-    height: 75vh;
-    box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1);
-  }
-}
-
-.removeVisiable {
-  width: 432px;
-
-  :global {
-    .n-card-header {
-      font-size: max(22px, 16Px);
-    }
-  }
-
-  .studentRemove {
-    padding: 0 40px;
-
-    p {
-      font-size: max(18px, 14Px);
-      color: #777777;
-      line-height: 30px;
-
-      span {
-        color: #EA4132;
-      }
-    }
-  }
-
-  .btnGroup {
-    padding: 32px 0;
-
-    :global {
-      .n-button {
-        height: 47px;
-        min-width: 156px;
-      }
-    }
-  }
-}
-
-.listSection {
-  padding: 0 0 12px;
-  display: flex;
-  flex-flow: row wrap;
-  justify-content: flex-start;
-  gap: 20px 2%;
-
-  &>div {
-    width: 49% !important;
-  }
-}
-
-.item {
-  cursor: pointer;
-  background: #F7F9FF;
-  border-radius: 13px;
-  padding: 0 17px 17px;
-  position: relative;
-  display: flex;
-  flex-direction: column;
-
-  .header {
-    display: flex;
-    align-items: center;
-    padding: 13px 0;
-
-    .navatar {
-      width: 60px;
-      height: 60px;
-      border-radius: 50%;
-      padding: 2px;
-      border: 1px solid #198CFE;
-      margin-right: 15px;
-      flex-shrink: 0;
-      background-color: #fff !important;
-
-      :global {
-        img {
-          border-radius: 50%;
-        }
-      }
-    }
-
-    .userInfo {
-      padding-top: 4px;
-      flex: 1;
-
-      h2 {
-        font-size: max(17px, 14Px);
-        font-weight: 600;
-        color: #131415;
-        line-height: 28px;
-      }
-
-      p {
-        font-size: max(16px, 12Px);
-        color: #777777;
-        line-height: 28px;
-      }
-    }
-
-    .ing,
-    .over {
-      position: absolute;
-      top: 0;
-      right: 0;
-      width: 121px;
-      height: 38px;
-      display: inline-block;
-    }
-
-    .ing {
-      background: url('./images/icon-ing.png') no-repeat center;
-      background-size: contain;
-    }
-
-    .over {
-      background: url('./images/icon-over.png') no-repeat center;
-      background-size: contain;
-    }
-  }
-
-  .content {
-    // display: flex;
-    // justify-content: space-between;
-    // align-items: flex-end;
-    flex: 1;
-    padding: 13px;
-    background: #FFFFFF;
-    border-radius: 10px;
-
-    .homeTitle {
-      font-size: max(17px, 14Px);
-      font-family: PingFangSC, PingFang SC;
-      font-weight: 600;
-      color: #000000;
-      padding-bottom: 5px;
-      display: flex;
-      align-items: center;
-      justify-content: space-between;
-
-      :global {
-        .n-space {
-          flex-shrink: 0;
-        }
-      }
-
-      &>p {
-        display: flex;
-        align-items: center;
-      }
-
-      .CLASSWORK,
-      .HOMEWORK {
-        padding: 2px 8px 1px;
-        border-radius: 4px;
-        font-size: max(13px, 11Px);
-        line-height: 18px;
-        margin-right: 7px;
-      }
-
-      .CLASSWORK {
-        color: #E24F4F;
-        background: #FFD2D2;
-      }
-
-      .HOMEWORK {
-        color: #3F8ADF;
-        background: #D2E9FF;
-
-      }
-    }
-
-    .homeContent {
-      padding-bottom: 5px;
-    }
-
-    .homeworkText {
-      display: flex;
-      align-items: flex-start;
-
-      .pSection {
-        max-width: 650px;
-      }
-
-      .p1,
-      .p2 {
-        white-space: nowrap;
-        overflow: hidden;
-        text-overflow: ellipsis;
-      }
-
-      .p1::before,
-      .p2::before {
-        content: '';
-        display: inline-block;
-        width: 5px;
-        height: 5px;
-        background: #198CFE;
-        margin-right: 7px;
-        border-radius: 50%;
-        flex-shrink: 0;
-        transform: translateY(-3px);
-      }
-
-      .p1 {
-        padding-bottom: 6px;
-      }
-
-      .p2::before {
-        background: #F44040;
-      }
-    }
-
-    .title {
-      font-size: max(13px, 12Px);
-      color: #777777;
-      flex-shrink: 0;
-    }
-
-    .text {
-      font-size: max(13px, 12Px);
-      font-weight: 500;
-      color: #333333;
-      line-height: 22px;
-    }
-
-    .errorBtn {
-      // min-width: 93px;
-      // height: 30px;
-      --n-height: 24px !important;
-      // background: #F94D50;
-      // border-radius: 7px;
-      --n-font-size: max(15px, 13Px);
-      font-weight: 500 !important;
-      // color: #FFFFFF;
-      line-height: 18px;
-    }
-  }
+.listWrap {
+  padding: 32px;
+  background-color: #fff;
+  border-radius: 20px;
+}
+
+.searchList {
+  .searchInput {
+    max-width: 260px;
+  }
+
+  // .CDatePickerItem {
+  //   :global {
+  //     .n-input {
+  //       width: 303px;
+  //     }
+  //   }
+  // }
+
+  :global {
+    .n-form.n-form--inline {
+      flex-wrap: wrap;
+    }
+
+    .n-form.n-form--inline .n-form-item {
+      margin-right: 18px;
+    }
+
+    // .n-form-item-blank>div {
+    //   .n-select {
+    //     min-width: 150px !important;
+    //     width: 150px !important;
+    //   }
+    // }
+  }
+}
+
+.infoListWrap {
+  min-height: calc(100vh - 150px) !important
+}
+
+.addBtnIcon {
+  width: 13Px !important;
+  height: 14Px !important;
+}
+
+.addBtn {
+  margin-bottom: 30px;
+  background: #198cfe !important;
+  border-radius: 7Px !important;
+  padding: 0 18Px !important;
+  font-weight: 600 !important;
+}
+
+.btnGroup {
+  padding: 40px 0;
+
+  :global {
+    .n-button {
+      height: 47px;
+      min-width: 156px;
+    }
+  }
+}
+
+.addClass {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding-top: 50px;
+}
+
+.listWrap {
+  min-height: 100%;
+  padding: 32px;
+  background-color: #fff;
+  border-radius: 20px;
+
+}
+
+.workVisiable {
+  width: 1258px;
+}
+
+.workContainer {
+  display: flex;
+  align-items: center;
+
+  .workTrain {
+    flex: 1;
+    height: 75vh;
+
+    &>div {
+      padding-top: 15px;
+    }
+  }
+
+  :global {
+    .train-container {
+      // max-height: calc(var(--window-page-lesson-height) - 135px) !important;
+      max-height: calc(var(--window-page-lesson-height) - 100px) !important;
+
+      .train-listSection {
+        min-height: calc(var(--window-page-lesson-height) - 100px) !important;
+      }
+    }
+  }
+
+  .resourceMain {
+    flex: 0 0 360px;
+    height: 75vh;
+    box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1);
+  }
+}
+
+.removeVisiable {
+  width: 432px;
+
+  :global {
+    .n-card-header {
+      font-size: max(22px, 16Px);
+    }
+  }
+
+  .studentRemove {
+    padding: 0 40px;
+
+    p {
+      font-size: max(18px, 14Px);
+      color: #777777;
+      line-height: 30px;
+
+      span {
+        color: #EA4132;
+      }
+    }
+  }
+
+  .btnGroup {
+    padding: 32px 0;
+
+    :global {
+      .n-button {
+        height: 47px;
+        min-width: 156px;
+      }
+    }
+  }
+}
+
+.listSection {
+  padding: 0 0 12px;
+  display: flex;
+  flex-flow: row wrap;
+  justify-content: flex-start;
+  gap: 20px 2%;
+
+  &>div {
+    width: 49% !important;
+  }
+}
+
+.theTooltip {
+  max-width: 650px !important;
+}
+
+.item {
+  cursor: pointer;
+  background: #F7F9FF;
+  border-radius: 13px;
+  padding: 0 17px 17px;
+  position: relative;
+  display: flex;
+  flex-direction: column;
+
+  .header {
+    display: flex;
+    align-items: center;
+    padding: 13px 0;
+
+    .navatar {
+      width: 60px;
+      height: 60px;
+      border-radius: 50%;
+      padding: 2px;
+      border: 1px solid #198CFE;
+      margin-right: 15px;
+      flex-shrink: 0;
+      background-color: #fff !important;
+
+      :global {
+        img {
+          border-radius: 50%;
+        }
+      }
+    }
+
+    .userInfo {
+      padding-top: 4px;
+      flex: 1;
+
+      h2 {
+        font-size: max(17px, 14Px);
+        font-weight: 600;
+        color: #131415;
+        line-height: 28px;
+      }
+
+      p {
+        font-size: max(16px, 12Px);
+        color: #777777;
+        line-height: 28px;
+      }
+    }
+
+    .ing,
+    .over {
+      position: absolute;
+      top: 0;
+      right: 0;
+      width: 121px;
+      height: 38px;
+      display: inline-block;
+    }
+
+    .ing {
+      background: url('./images/icon-ing.png') no-repeat center;
+      background-size: contain;
+    }
+
+    .over {
+      background: url('./images/icon-over.png') no-repeat center;
+      background-size: contain;
+    }
+  }
+
+  .content {
+    // display: flex;
+    // justify-content: space-between;
+    // align-items: flex-end;
+    flex: 1;
+    padding: 13px;
+    background: #FFFFFF;
+    border-radius: 10px;
+
+    .homeTitle {
+      font-size: max(17px, 14Px);
+      font-family: PingFangSC, PingFang SC;
+      font-weight: 600;
+      color: #000000;
+      padding-bottom: 5px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+
+      :global {
+        .n-space {
+          flex-shrink: 0;
+        }
+      }
+
+      &>p {
+        display: flex;
+        align-items: center;
+      }
+
+      .CLASSWORK,
+      .HOMEWORK {
+        padding: 2px 8px 1px;
+        border-radius: 4px;
+        font-size: max(13px, 11Px);
+        line-height: 18px;
+        margin-right: 7px;
+      }
+
+      .CLASSWORK {
+        color: #E24F4F;
+        background: #FFD2D2;
+      }
+
+      .HOMEWORK {
+        color: #3F8ADF;
+        background: #D2E9FF;
+
+      }
+    }
+
+    .homeContent {
+      padding-bottom: 5px;
+    }
+
+    .homeworkText {
+      display: flex;
+      align-items: flex-start;
+
+      .pSection {
+        max-width: 650px;
+      }
+
+      .p1,
+      .p2 {
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+      }
+
+      .p1::before,
+      .p2::before {
+        content: '';
+        display: inline-block;
+        width: 5px;
+        height: 5px;
+        background: #198CFE;
+        margin-right: 7px;
+        border-radius: 50%;
+        flex-shrink: 0;
+        transform: translateY(-3px);
+      }
+
+      .p1 {
+        padding-bottom: 6px;
+      }
+
+      .p2::before {
+        background: #F44040;
+      }
+    }
+
+    .title {
+      font-size: max(13px, 12Px);
+      color: #777777;
+      flex-shrink: 0;
+    }
+
+    .text {
+      font-size: max(13px, 12Px);
+      font-weight: 500;
+      color: #333333;
+      line-height: 22px;
+
+      :global {
+        .showContentWidthWrap {
+          max-width: 100% !important;
+          display: inline;
+        }
+      }
+    }
+
+    .errorBtn {
+      // min-width: 93px;
+      // height: 30px;
+      --n-height: 24px !important;
+      // background: #F94D50;
+      // border-radius: 7px;
+      --n-font-size: max(15px, 13Px);
+      font-weight: 500 !important;
+      // color: #FFFFFF;
+      line-height: 18px;
+    }
+  }
 }

+ 75 - 10
src/views/homework-record/index.tsx

@@ -10,6 +10,7 @@ import {
   NModal,
   NSpace,
   NSpin,
+  NTooltip,
   useMessage
 } from 'naive-ui';
 import SearchInput from '@/components/searchInput';
@@ -32,6 +33,8 @@ import { useResizeObserver } from '@vueuse/core';
 import { nextTick } from 'process';
 import PreviewWindow from '../preview-window';
 import { state as baseState } from '@/state';
+import { evaluateDifficult } from '/src/utils/contants';
+import TheTooltip from '/src/components/TheTooltip';
 
 export const getCurrentMonth = () => {
   return [dayjs().startOf('month').valueOf(), dayjs().endOf('month').valueOf()];
@@ -146,18 +149,43 @@ export default defineComponent({
             item.studentLessonTrainingDetails.length > 0
           ) {
             item.studentLessonTrainingDetails.forEach((child: any) => {
+              const trainingContent = child.trainingContent
+                ? JSON.parse(child.trainingContent)
+                : null;
               if (child.trainingType === 'PRACTICE' && child.musicName) {
                 pTitle += pTitle
-                  ? '、《' + child.musicName + '》'
-                  : '练习曲目《' + child.musicName + '》';
+                  ? '《' + child.musicName + '》'
+                  : '练习曲目:《' + child.musicName + '》';
+
+                if (trainingContent) {
+                  const tempList = [
+                    `${trainingContent.practiceChapterBegin}-${trainingContent.practiceChapterEnd}小节`,
+                    `速度${trainingContent.practiceSpeed}`,
+                    `${trainingContent.trainingTimes}分钟`
+                  ];
+                  pTitle += tempList.join(' | ') + ';';
+                }
               }
               if (child.trainingType === 'EVALUATION' && child.musicName) {
                 eTitle += eTitle
-                  ? '、《' + child.musicName + '》'
-                  : '评测曲目《' + child.musicName + '》';
+                  ? '《' + child.musicName + '》'
+                  : '评测曲目:《' + child.musicName + '》';
+
+                if (trainingContent) {
+                  const tempList = [
+                    `${evaluateDifficult[trainingContent.evaluateDifficult]}`,
+                    trainingContent.practiceChapterBegin ||
+                    trainingContent.practiceChapterEnd
+                      ? `${trainingContent.practiceChapterBegin}-${trainingContent.practiceChapterEnd}小节`
+                      : '全部小节',
+                    `${trainingContent.trainingTimes}分合格`
+                  ];
+                  eTitle += tempList.join(' | ') + ';';
+                }
               }
             });
           }
+
           item.pTitle = pTitle;
           item.eTitle = eTitle;
 
@@ -526,14 +554,51 @@ export default defineComponent({
                         <span class={styles.title}>作业内容:</span>
                         <div class={styles.pSection}>
                           {item.pTitle && (
-                            <p class={[styles.text, styles.p1]}>
-                              {item.pTitle}
-                            </p>
+                            <NTooltip
+                              trigger="hover"
+                              class={styles.theTooltip}
+                              delay={500}>
+                              {{
+                                trigger: () => (
+                                  <p
+                                    class={[
+                                      styles.text,
+                                      styles.p1,
+                                      styles.theTooltip
+                                    ]}>
+                                    {item.pTitle}
+                                  </p>
+                                ),
+                                default: () => item.pTitle
+                              }}
+                            </NTooltip>
                           )}
                           {item.eTitle && (
-                            <p class={[styles.text, styles.p2]}>
-                              {item.eTitle}
-                            </p>
+                            // <p class={[styles.text, styles.p2]}>
+                            //   <TheTooltip
+                            //     maxWidth={500}
+                            //     content={item.eTitle}
+                            //     style={{ maxWidth: '100% !important' }}
+                            //   />
+                            // </p>
+                            <NTooltip
+                              trigger="hover"
+                              class={styles.theTooltip}
+                              delay={500}>
+                              {{
+                                trigger: () => (
+                                  <p
+                                    class={[
+                                      styles.text,
+                                      styles.p2,
+                                      styles.theTooltip
+                                    ]}>
+                                    {item.eTitle}
+                                  </p>
+                                ),
+                                default: () => item.eTitle
+                              }}
+                            </NTooltip>
                           )}
                         </div>
                       </div>

+ 800 - 797
src/views/prepare-lessons/components/lesson-main/courseware-presets/index.tsx

@@ -1,797 +1,800 @@
-import {
-  computed,
-  defineComponent,
-  onMounted,
-  reactive,
-  ref,
-  watch
-} from 'vue';
-import styles from './index.module.less';
-import {
-  NButton,
-  NTooltip,
-  NIcon,
-  NImage,
-  NModal,
-  NScrollbar,
-  NSpin,
-  NTabPane,
-  NTabs,
-  useMessage,
-  NPopselect
-} from 'naive-ui';
-import { usePrepareStore } from '/src/store/modules/prepareLessons';
-import add from '@/views/studentList/images/add.png';
-// import iconSlideRight from '../../../images/icon-slide-right.png';
-import CoursewareType from '../../../model/courseware-type';
-import TheEmpty from '/src/components/TheEmpty';
-import RelatedClass from '../../../model/related-class';
-import { state } from '/src/state';
-import { useResizeObserver } from '@vueuse/core';
-import AttendClass from '/src/views/prepare-lessons/model/attend-class';
-import {
-  api_addByOpenCourseware,
-  api_teacherChapterLessonCoursewareRemove,
-  teacherChapterLessonCoursewareList,
-  courseScheduleStart
-} from '../../../api';
-import { useRoute, useRouter } from 'vue-router';
-import TheMessageDialog from '/src/components/TheMessageDialog';
-import { eventGlobal, fscreen } from '/src/utils';
-import PreviewWindow from '/src/views/preview-window';
-import Related from './related';
-import Train from '../train';
-import ResourceMain from '../../resource-main';
-
-export default defineComponent({
-  name: 'courseware-presets',
-  props: {
-    addParam: {
-      type: Object,
-      default: () => ({})
-    }
-  },
-  emits: ['change'],
-  setup(props, { emit }) {
-    const prepareStore = usePrepareStore();
-    const message = useMessage();
-    const route = useRoute();
-    const router = useRouter();
-    const localStorageSubjectId = localStorage.getItem(
-      'prepareLessonSubjectId'
-    );
-
-    const forms = reactive({
-      // 选取参数带的,后取缓存
-      leftWidth: '100%',
-      rightWidth: '0',
-      messageLoading: false,
-      instrumentId: route.query.instrumentId
-        ? Number(route.query.instrumentId)
-        : localStorageSubjectId
-        ? Number(localStorageSubjectId)
-        : '',
-      courseScheduleSubjectId: route.query.courseScheduleSubjectId,
-      classGroupId: route.query.classGroupId,
-      preStudentNum: route.query.preStudentNum,
-      bodyWidth: '100%',
-      loading: false,
-      openLoading: false,
-      showRelatedClass: false,
-      tableList: [] as any,
-      openTableShow: true, // 是否显示
-      openTableList: [] as any,
-      selectItem: {} as any,
-      editTitleVisiable: false,
-      editTitle: null,
-      editBtnLoading: false,
-      preRemoveVisiable: false,
-      addVisiable: false, // 是否有添加的课件
-      carouselIndex: 0,
-      showAttendClass: false,
-      attendClassType: 'change', //
-      attendClassItem: {} as any,
-      previewModal: false,
-      previewParams: {
-        type: '',
-        courseId: '',
-        instrumentId: '',
-        detailId: ''
-      } as any,
-      workVisiable: false,
-      wikiCategoryIdChild: null
-    });
-
-    const getCoursewareList = async () => {
-      forms.loading = true;
-      try {
-        // 判断是否有选择对应的课件 或声部
-        if (!prepareStore.getSelectKey) return (forms.loading = false);
-
-        const { data } = await teacherChapterLessonCoursewareList({
-          instrumentId: prepareStore.getInstrumentId,
-          coursewareDetailKnowledgeId: prepareStore.getSelectKey
-        });
-        if (!Array.isArray(data)) {
-          return;
-        }
-        const tempList: any = [];
-        data.forEach((item: any) => {
-          const firstItem: any =
-            item.chapterKnowledgeList[0]?.chapterKnowledgeMaterialList[0];
-          tempList.push({
-            id: item.id,
-            lessonPreTrainingId: item.lessonPreTrainingId,
-            openFlag: item.openFlag,
-            openFlagEnable: item.openFlagEnable,
-            instrumentNames: item.instrumentNames,
-            fromChapterLessonCoursewareId: item.fromChapterLessonCoursewareId,
-            name: item.name,
-            coverImg: firstItem?.bizInfo.coverImg,
-            type: firstItem?.bizInfo.type,
-            isNotWork: item.lessonPreTrainingNum <= 0 ? true : false // 是否布置作业
-          });
-        });
-        forms.tableList = tempList;
-      } catch {
-        //
-      }
-      forms.loading = false;
-    };
-
-    // 监听选择的key 左侧选择了其它的课
-    watch(
-      () => [prepareStore.getSelectKey, prepareStore.getInstrumentId],
-      async () => {
-        eventGlobal.emit('openCoursewareChanged');
-        await getCoursewareList();
-        // await getOpenCoursewareList();
-
-        subjectRef.value?.syncBarPosition();
-      }
-    );
-
-    watch(
-      () => prepareStore.getInstrumentList,
-      () => {
-        checkInstrumentIds();
-      }
-    );
-
-    const checkInstrumentIds = () => {
-      const instrumentsList = prepareStore.getSingleInstrumentList;
-
-      // 并且没有声部时才会更新
-      if (instrumentsList.length > 0) {
-        const prepareLessonCourseWareSubjectIsNull = sessionStorage.getItem(
-          'prepareLessonCourseWareSubjectIsNull'
-        );
-        if (prepareLessonCourseWareSubjectIsNull === 'true') {
-          prepareStore.setInstrumentId('');
-          return;
-        }
-
-        // 并且声部在列表中
-        const localStorageSubjectId = localStorage.getItem(
-          'prepareLessonSubjectId'
-        );
-        // // 先取 上次上课声部,在取班级声部 最后取缓存
-        let instrumentId = null;
-        let index = -1;
-        if (forms.courseScheduleSubjectId) {
-          // 判断浏览器上面是否有
-          index = instrumentsList.findIndex(
-            (subject: any) => subject.id == forms.courseScheduleSubjectId
-          );
-          if (index >= 0) {
-            instrumentId = Number(forms.courseScheduleSubjectId);
-          }
-        }
-        // 判断班级上面声部 & 还没有声部
-        if (forms.instrumentId && !instrumentId) {
-          // 判断浏览器上面是否有
-          index = instrumentsList.findIndex(
-            (subject: any) => subject.id == forms.instrumentId
-          );
-          if (index >= 0) {
-            instrumentId = Number(forms.instrumentId);
-          }
-        }
-        // 缓存声部 & 还没有声部
-        if (localStorageSubjectId && !instrumentId) {
-          // 判断浏览器上面是否有
-          index = instrumentsList.findIndex(
-            (subject: any) => subject.id == localStorageSubjectId
-          );
-          if (index >= 0) {
-            instrumentId = Number(localStorageSubjectId);
-          }
-        }
-        // 判断是否选择为空
-        if (instrumentId && index >= 0) {
-          prepareStore.setSubjectId(instrumentId);
-          // forms.instrumentId = instrumentId;
-        } else {
-          // 判断是否有缓存
-          // prepareStore.setSubjectId(instrumentsList[0].id);
-          // forms.instrumentId = instrumentsList[0].id;
-        }
-
-        // 保存
-        localStorage.setItem(
-          'prepareLessonSubjectId',
-          prepareStore.getInstrumentId as any
-        );
-
-        subjectRef.value?.syncBarPosition();
-      }
-    };
-
-    const getInitInstrumentId = () => {
-      let instrumentId: any = '';
-      prepareStore.getInstrumentList.forEach((item: any) => {
-        if (Array.isArray(item.instruments)) {
-          item.instruments.forEach((child: any) => {
-            if (child.id === prepareStore.getInstrumentId) {
-              instrumentId = child.id;
-            }
-          });
-        }
-      });
-      if (instrumentId) {
-        forms.wikiCategoryIdChild = instrumentId;
-      }
-    };
-    const subjectRef = ref();
-    onMounted(async () => {
-      useResizeObserver(
-        document.querySelector('#presetsLeftRef') as HTMLElement,
-        (entries: any) => {
-          const entry = entries[0];
-          const { width } = entry.contentRect;
-          forms.leftWidth = width + 'px';
-        }
-      );
-      useResizeObserver(
-        document.querySelector('#presetsRightRef') as HTMLElement,
-        (entries: any) => {
-          const entry = entries[0];
-          const { width } = entry.contentRect;
-          forms.rightWidth = width + 'px';
-        }
-      );
-
-      prepareStore.setClassGroupId(route.query.classGroupId as any);
-      if (!prepareStore.getInstrumentId) {
-        // 获取教材分类列表
-        checkInstrumentIds();
-      } else {
-        getInitInstrumentId();
-      }
-
-      await getCoursewareList();
-
-      if (props.addParam.isAdd) {
-        forms.addVisiable = true;
-      }
-    });
-
-    // 删除
-    const onRemove = async () => {
-      forms.messageLoading = true;
-      try {
-        await api_teacherChapterLessonCoursewareRemove({
-          id: forms.selectItem.id
-        });
-        message.success('删除成功');
-        getCoursewareList();
-        // getOpenCoursewareList();
-        eventGlobal.emit('openCoursewareChanged');
-        forms.preRemoveVisiable = false;
-      } catch {
-        //
-      }
-      setTimeout(() => {
-        forms.messageLoading = false;
-      }, 100);
-    };
-
-    // 添加课件
-    const onAddCourseware = async (item: any) => {
-      if (forms.messageLoading) return;
-      forms.messageLoading = true;
-      try {
-        await api_addByOpenCourseware({ id: item.id });
-        message.success('添加成功');
-        getCoursewareList();
-        // getOpenCoursewareList();
-        eventGlobal.emit('openCoursewareChanged');
-      } catch {
-        //
-      }
-      setTimeout(() => {
-        forms.messageLoading = false;
-      }, 100);
-    };
-
-    // 预览上课
-    const onPreviewAttend = (id: string) => {
-      // 判断是否在应用里面
-      if (window.matchMedia('(display-mode: standalone)').matches) {
-        state.application = window.matchMedia(
-          '(display-mode: standalone)'
-        ).matches;
-        forms.previewModal = true;
-        fscreen();
-        forms.previewParams = {
-          type: 'preview',
-          courseId: id,
-          instrumentId: prepareStore.getInstrumentId,
-          detailId: prepareStore.getSelectKey,
-          lessonCourseId: prepareStore.getBaseCourseware.id
-        };
-      } else {
-        const { href } = router.resolve({
-          path: '/attend-class',
-          query: {
-            type: 'preview',
-            courseId: id,
-            instrumentId: prepareStore.getInstrumentId,
-            detailId: prepareStore.getSelectKey,
-            lessonCourseId: prepareStore.getBaseCourseware.id
-          }
-        });
-        window.open(href, +new Date() + '');
-      }
-    };
-
-    const onStartClass = async (
-      item: any,
-      classGroupId: any,
-      instrumentId?: any
-    ) => {
-      if (classGroupId) {
-        // 开始上课
-        const res = await courseScheduleStart({
-          lessonCoursewareKnowledgeDetailId: prepareStore.selectKey,
-          classGroupId: classGroupId,
-          useChapterLessonCoursewareId: item.id
-          // instrumentId: prepareStore.getInstrumentId
-        });
-        if (window.matchMedia('(display-mode: standalone)').matches) {
-          state.application = window.matchMedia(
-            '(display-mode: standalone)'
-          ).matches;
-          forms.previewModal = true;
-          fscreen();
-          forms.previewParams = {
-            type: 'class',
-            classGroupId: classGroupId,
-            courseId: item.id,
-            instrumentId: instrumentId || route.query.instrumentId,
-            detailId: prepareStore.getSelectKey,
-            classId: res.data,
-            lessonCourseId: prepareStore.getBaseCourseware.id,
-            preStudentNum: forms.preStudentNum
-          };
-        } else {
-          const { href } = router.resolve({
-            path: '/attend-class',
-            query: {
-              type: 'class',
-              classGroupId: classGroupId,
-              courseId: item.id,
-              // instrumentId: prepareStore.getInstrumentId,
-              instrumentId: instrumentId || route.query.instrumentId,
-              detailId: prepareStore.getSelectKey,
-              classId: res.data,
-              lessonCourseId: prepareStore.getBaseCourseware.id,
-              preStudentNum: forms.preStudentNum
-            }
-          });
-          window.open(href, +new Date() + '');
-        }
-      } else {
-        forms.showAttendClass = true;
-        forms.attendClassType = 'change';
-        forms.attendClassItem = item;
-      }
-    };
-
-    const selectChildObj = (item: any, index: number) => {
-      const obj: any = {};
-      item?.forEach((child: any) => {
-        if (child.id === forms.wikiCategoryIdChild) {
-          obj.selected = true;
-          obj.name = child.name;
-        }
-      });
-      return obj;
-    };
-
-    const tabInstrumentValue = computed(() => {
-      let instrumentId: any = prepareStore.getInstrumentId
-        ? prepareStore.getInstrumentId
-        : '';
-      prepareStore.getFormatInstrumentList.forEach((item: any) => {
-        if (Array.isArray(item.instruments)) {
-          item.instruments.forEach((child: any) => {
-            if (child.id === prepareStore.getInstrumentId) {
-              instrumentId = item.id + '';
-            }
-          });
-        }
-      });
-      return instrumentId;
-    });
-    return () => (
-      <div
-        class={[
-          styles.coursewarePresetsContainer,
-          forms.openTableShow && styles.rightLineShow
-        ]}>
-        <div
-          class={styles.presetsLeft}
-          id="presetsLeftRef"
-          style={{ width: `calc(${forms.leftWidth} - ${forms.rightWidth})` }}>
-          <NTabs
-            ref={subjectRef}
-            defaultValue=""
-            paneClass={styles.paneTitle}
-            justifyContent="start"
-            paneWrapperClass={styles.paneWrapperContainer}
-            value={tabInstrumentValue.value}
-            onUpdate:value={(val: any) => {
-              console.log(val, 'item.id', prepareStore.getFormatInstrumentList);
-              prepareStore.getFormatInstrumentList.forEach((item: any) => {
-                if (item.value.toString() === val.toString()) {
-                  prepareStore.setInstrumentId(val);
-                  // 保存
-                  forms.instrumentId = val;
-                  forms.wikiCategoryIdChild = null;
-                }
-              });
-
-              if (!val) {
-                prepareStore.setInstrumentId(val);
-                // 保存
-                forms.instrumentId = val;
-                forms.wikiCategoryIdChild = null;
-                sessionStorage.setItem(
-                  'prepareLessonCourseWareSubjectIsNull',
-                  val ? 'false' : 'true'
-                );
-              }
-            }}
-            v-slots={{
-              suffix: () => (
-                <NButton
-                  class={styles.addBtn}
-                  type="primary"
-                  bordered={false}
-                  onClick={() => {
-                    eventGlobal.emit('teacher-slideshow', true);
-                    emit('change', {
-                      status: true,
-                      type: 'create'
-                    });
-                  }}>
-                  <NImage
-                    class={styles.addBtnIcon}
-                    previewDisabled
-                    src={add}></NImage>
-                  创建课件
-                </NButton>
-              )
-            }}>
-            {[
-              { name: '全部乐器', id: '', label: '全部乐器', value: '' },
-              ...prepareStore.getFormatInstrumentList
-            ].map((item: any, index: number) => (
-              <NTabPane
-                name={`${item.value}`}
-                tab={item.label}
-                disabled={item.instruments?.length > 0}
-                displayDirective="if">
-                {{
-                  tab: () =>
-                    item.instruments?.length > 0 ? (
-                      <NPopselect
-                        options={item.instruments}
-                        trigger="hover"
-                        v-model:value={forms.wikiCategoryIdChild}
-                        onUpdate:value={(val: any) => {
-                          // onSearch();
-                          prepareStore.setInstrumentId(val);
-                          // 保存
-                          forms.instrumentId = val;
-
-                          if (!val) {
-                            sessionStorage.setItem(
-                              'prepareLessonCourseWareSubjectIsNull',
-                              val ? 'false' : 'true'
-                            );
-                          }
-                        }}
-                        key={item.id}
-                        class={styles.popSelect}>
-                        <span
-                          class={[
-                            styles.textBtn,
-                            selectChildObj(item.instruments, index).selected &&
-                              styles.textBtnActive
-                          ]}>
-                          {selectChildObj(item.instruments, index).label ||
-                            item.label}
-                          <i class={styles.iconArrow}></i>
-                        </span>
-                      </NPopselect>
-                    ) : (
-                      item.label
-                    )
-                }}
-              </NTabPane>
-            ))}
-          </NTabs>
-          <NSpin show={forms.loading}>
-            <NScrollbar class={styles.coursewarePresets}>
-              <div style={{ overflow: 'hidden' }}>
-                <div
-                  class={[
-                    styles.list,
-                    !forms.loading &&
-                      forms.tableList.length <= 0 &&
-                      styles.listEmpty
-                  ]}>
-                  {forms.tableList.map((item: any) => (
-                    <div class={[styles.itemWrap, styles.itemBlock, 'row-nav']}>
-                      <div class={styles.itemWrapBox}>
-                        <CoursewareType
-                          operate
-                          isEditName
-                          item={item}
-                          onClick={() => onPreviewAttend(item.id)}
-                          // onEditName={() => {
-                          //   forms.selectItem = item;
-                          //   forms.editTitle = item.name;
-                          //   forms.editTitleVisiable = true;
-                          // }}
-                          onEdit={() => {
-                            //
-                            eventGlobal.emit('teacher-slideshow', true);
-                            emit('change', {
-                              status: true,
-                              type: 'update',
-                              groupItem: { id: item.id }
-                            });
-                          }}
-                          onStartClass={() =>
-                            onStartClass(item, forms.classGroupId)
-                          }
-                          onDelete={() => {
-                            forms.selectItem = item;
-                            forms.preRemoveVisiable = true;
-                          }}
-                          // 布置作业
-                          onWork={() => {
-                            forms.workVisiable = true;
-                            forms.selectItem = item;
-                          }}
-                        />
-                      </div>
-                    </div>
-                  ))}
-                  {!forms.loading && forms.tableList.length <= 0 && (
-                    <TheEmpty
-                      class={styles.empty1}
-                      description="当前章节暂无课件,快点击右上角创建课件吧"
-                    />
-                  )}
-                </div>
-              </div>
-            </NScrollbar>
-          </NSpin>
-        </div>
-
-        <div class={styles.presetsRight} id="presetsRightRef">
-          <NTooltip showArrow={false} animated={false} duration={0} delay={0}>
-            {{
-              trigger: () => (
-                <div
-                  class={[
-                    styles.presetsArrar,
-                    !forms.openTableShow && styles.presetsArrarActive
-                  ]}
-                  onClick={() => (forms.openTableShow = !forms.openTableShow)}>
-                  <NIcon>
-                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
-                      <path
-                        d="M16.62 2.99a1.25 1.25 0 0 0-1.77 0L6.54 11.3a.996.996 0 0 0 0 1.41l8.31 8.31c.49.49 1.28.49 1.77 0s.49-1.28 0-1.77L9.38 12l7.25-7.25c.48-.48.48-1.28-.01-1.76z"
-                        fill="currentColor"></path>
-                    </svg>
-                  </NIcon>
-                </div>
-              ),
-              default: () => <div>{forms.openTableShow ? '收起' : '展开'}</div>
-            }}
-          </NTooltip>
-
-          <Related
-            onMore={() => (forms.showRelatedClass = true)}
-            onAdd={(item: any) => {
-              onAddCourseware(item);
-            }}
-            onLook={(item: any) => {
-              onPreviewAttend(item.id);
-            }}
-          />
-        </div>
-        {/* )} */}
-
-        <NModal
-          v-model:show={forms.showRelatedClass}
-          preset="card"
-          showIcon={false}
-          class={['modalTitle background', styles.attendClassModal1]}
-          title={'相关课件'}
-          blockScroll={false}>
-          <RelatedClass
-            tableList={forms.tableList}
-            instrumentList={prepareStore.getInstrumentList}
-            instrumentId={prepareStore.getInstrumentId as any}
-            coursewareDetailKnowledgeId={prepareStore.getSelectKey}
-            onClose={() => (forms.showRelatedClass = false)}
-            onAdd={(item: any) => onAddCourseware(item)}
-            onClick={(item: any) => {
-              onPreviewAttend(item.id);
-              forms.showRelatedClass = false;
-            }}
-          />
-        </NModal>
-
-        {/* <NModal
-          v-model:show={forms.editTitleVisiable}
-          preset="card"
-          class={['modalTitle', styles.removeVisiable1]}
-          title={'课件重命名'}>
-          <div class={styles.studentRemove}>
-            <NInput
-              placeholder="请输入课件名称"
-              v-model:value={forms.editTitle}
-              maxlength={15}
-              onKeyup={(e: any) => {
-                if (e.code === 'ArrowLeft' || e.code === 'ArrowRight') {
-                  e.stopPropagation();
-                }
-              }}
-            />
-
-            <NSpace class={styles.btnGroupModal} justify="center">
-              <NButton round onClick={() => (forms.editTitleVisiable = false)}>
-                取消
-              </NButton>
-              <NButton
-                round
-                type="primary"
-                onClick={onEditTitleSubmit}
-                loading={forms.editBtnLoading}>
-                确定
-              </NButton>
-            </NSpace>
-          </div>
-        </NModal> */}
-
-        <NModal
-          v-model:show={forms.preRemoveVisiable}
-          preset="card"
-          class={['modalTitle', styles.removeVisiable1]}
-          title={'删除课件'}>
-          <TheMessageDialog
-            content={`<p style="text-align: left;">请确认是否删除【${forms.selectItem.name}】,删除后不可恢复</p>`}
-            cancelButtonText="取消"
-            confirmButtonText="确认"
-            loading={forms.messageLoading}
-            onClose={() => (forms.preRemoveVisiable = false)}
-            onConfirm={() => onRemove()}
-          />
-        </NModal>
-
-        <NModal
-          v-model:show={forms.addVisiable}
-          preset="card"
-          class={['modalTitle', styles.removeVisiable1]}
-          title={'保存成功'}>
-          <TheMessageDialog
-            content={`<p style="text-align: left;">【${props.addParam.name}】暂未设置课件作业,是否现在去设置课件作业</p>`}
-            cancelButtonText="稍后设置"
-            confirmButtonText="立即设置"
-            // loading={forms.messageLoading}
-            onClose={() => (forms.addVisiable = false)}
-            onConfirm={() => {
-              forms.addVisiable = false;
-              forms.workVisiable = true;
-              forms.selectItem = {
-                id: props.addParam.id,
-                name: props.addParam.name
-              };
-            }}
-          />
-        </NModal>
-
-        {/* 应用内预览或上课 */}
-        <PreviewWindow
-          v-model:show={forms.previewModal}
-          type="attend"
-          params={forms.previewParams}
-        />
-
-        <NModal
-          v-model:show={forms.showAttendClass}
-          preset="card"
-          showIcon={false}
-          class={['modalTitle background', styles.attendClassModal]}
-          title={'选择班级'}
-          blockScroll={false}>
-          <AttendClass
-            onClose={() => (forms.showAttendClass = false)}
-            type={forms.attendClassType}
-            onPreview={(item: any) => {
-              if (window.matchMedia('(display-mode: standalone)').matches) {
-                state.application = window.matchMedia(
-                  '(display-mode: standalone)'
-                ).matches;
-                forms.previewModal = true;
-                forms.previewParams = {
-                  ...item
-                };
-              } else {
-                const { href } = router.resolve({
-                  path: '/attend-class',
-                  query: {
-                    ...item
-                  }
-                });
-                window.open(href, +new Date() + '');
-              }
-            }}
-            onConfirm={async (item: any) => {
-              onStartClass(
-                forms.attendClassItem,
-                item.classGroupId,
-                item.instrumentId
-              );
-            }}
-          />
-        </NModal>
-
-        <NModal
-          v-model:show={forms.workVisiable}
-          preset="card"
-          class={['modalTitle background', styles.workVisiable]}
-          title={
-            forms.selectItem.lessonPreTrainingId ? '编辑作业' : '创建作业'
-          }>
-          <div id="model-homework-height" class={styles.workContainer}>
-            <div class={styles.workTrain}>
-              <Train
-                cardType="prepare"
-                lessonPreTraining={{
-                  title: forms.selectItem.name + '-课后作业',
-                  chapterId: forms.selectItem.id, // 课件编号
-                  id: forms.selectItem.lessonPreTrainingId // 作业编号
-                }}
-                onChange={(val: any) => {
-                  forms.workVisiable = val.status;
-                  getCoursewareList();
-                }}
-              />
-            </div>
-            <div class={styles.resourceMain}>
-              <ResourceMain cardType="prepare" />
-            </div>
-          </div>
-        </NModal>
-      </div>
-    );
-  }
-});
+import {
+  computed,
+  defineComponent,
+  onMounted,
+  reactive,
+  ref,
+  watch
+} from 'vue';
+import styles from './index.module.less';
+import {
+  NButton,
+  NTooltip,
+  NIcon,
+  NImage,
+  NModal,
+  NScrollbar,
+  NSpin,
+  NTabPane,
+  NTabs,
+  useMessage,
+  NPopselect
+} from 'naive-ui';
+import { usePrepareStore } from '/src/store/modules/prepareLessons';
+import add from '@/views/studentList/images/add.png';
+// import iconSlideRight from '../../../images/icon-slide-right.png';
+import CoursewareType from '../../../model/courseware-type';
+import TheEmpty from '/src/components/TheEmpty';
+import RelatedClass from '../../../model/related-class';
+import { state } from '/src/state';
+import { useResizeObserver } from '@vueuse/core';
+import AttendClass from '/src/views/prepare-lessons/model/attend-class';
+import {
+  api_addByOpenCourseware,
+  api_teacherChapterLessonCoursewareRemove,
+  teacherChapterLessonCoursewareList,
+  courseScheduleStart
+} from '../../../api';
+import { useRoute, useRouter } from 'vue-router';
+import TheMessageDialog from '/src/components/TheMessageDialog';
+import { eventGlobal, fscreen } from '/src/utils';
+import PreviewWindow from '/src/views/preview-window';
+import Related from './related';
+import Train from '../train';
+import ResourceMain from '../../resource-main';
+
+export default defineComponent({
+  name: 'courseware-presets',
+  props: {
+    addParam: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  emits: ['change'],
+  setup(props, { emit }) {
+    const prepareStore = usePrepareStore();
+    const message = useMessage();
+    const route = useRoute();
+    const router = useRouter();
+    const localStorageSubjectId = localStorage.getItem(
+      'prepareLessonSubjectId'
+    );
+
+    const forms = reactive({
+      // 选取参数带的,后取缓存
+      leftWidth: '100%',
+      rightWidth: '0',
+      messageLoading: false,
+      instrumentId: route.query.instrumentId
+        ? Number(route.query.instrumentId)
+        : localStorageSubjectId
+        ? Number(localStorageSubjectId)
+        : '',
+      courseScheduleSubjectId: route.query.courseScheduleSubjectId,
+      classGroupId: route.query.classGroupId,
+      preStudentNum: route.query.preStudentNum,
+      bodyWidth: '100%',
+      loading: false,
+      openLoading: false,
+      showRelatedClass: false,
+      tableList: [] as any,
+      openTableShow: true, // 是否显示
+      openTableList: [] as any,
+      selectItem: {} as any,
+      editTitleVisiable: false,
+      editTitle: null,
+      editBtnLoading: false,
+      preRemoveVisiable: false,
+      addVisiable: false, // 是否有添加的课件
+      carouselIndex: 0,
+      showAttendClass: false,
+      attendClassType: 'change', //
+      attendClassItem: {} as any,
+      previewModal: false,
+      previewParams: {
+        type: '',
+        courseId: '',
+        instrumentId: '',
+        detailId: ''
+      } as any,
+      workVisiable: false,
+      wikiCategoryIdChild: null
+    });
+
+    const getCoursewareList = async () => {
+      forms.loading = true;
+      try {
+        // 判断是否有选择对应的课件 或声部
+        if (!prepareStore.getSelectKey) return (forms.loading = false);
+
+        const { data } = await teacherChapterLessonCoursewareList({
+          instrumentId: prepareStore.getInstrumentId,
+          coursewareDetailKnowledgeId: prepareStore.getSelectKey
+        });
+        if (!Array.isArray(data)) {
+          return;
+        }
+        const tempList: any = [];
+        data.forEach((item: any) => {
+          // const firstItem: any =
+          //   item.chapterKnowledgeList[0]?.chapterKnowledgeMaterialList[0];
+
+          const firstItem: any =
+            item.chapterKnowledgeList[0]?.chapterKnowledgeMaterialList;
+          tempList.push({
+            id: item.id,
+            lessonPreTrainingId: item.lessonPreTrainingId,
+            openFlag: item.openFlag,
+            openFlagEnable: item.openFlagEnable,
+            instrumentNames: item.instrumentNames,
+            fromChapterLessonCoursewareId: item.fromChapterLessonCoursewareId,
+            name: item.name,
+            coverImg: firstItem && firstItem[0]?.bizInfo.coverImg,
+            type: firstItem && firstItem[0]?.bizInfo.type,
+            isNotWork: item.lessonPreTrainingNum <= 0 ? true : false // 是否布置作业
+          });
+        });
+        forms.tableList = tempList;
+      } catch {
+        //
+      }
+      forms.loading = false;
+    };
+
+    // 监听选择的key 左侧选择了其它的课
+    watch(
+      () => [prepareStore.getSelectKey, prepareStore.getInstrumentId],
+      async () => {
+        eventGlobal.emit('openCoursewareChanged');
+        await getCoursewareList();
+        // await getOpenCoursewareList();
+
+        subjectRef.value?.syncBarPosition();
+      }
+    );
+
+    watch(
+      () => prepareStore.getInstrumentList,
+      () => {
+        checkInstrumentIds();
+      }
+    );
+
+    const checkInstrumentIds = () => {
+      const instrumentsList = prepareStore.getSingleInstrumentList;
+
+      // 并且没有声部时才会更新
+      if (instrumentsList.length > 0) {
+        const prepareLessonCourseWareSubjectIsNull = sessionStorage.getItem(
+          'prepareLessonCourseWareSubjectIsNull'
+        );
+        if (prepareLessonCourseWareSubjectIsNull === 'true') {
+          prepareStore.setInstrumentId('');
+          return;
+        }
+
+        // 并且声部在列表中
+        const localStorageSubjectId = localStorage.getItem(
+          'prepareLessonSubjectId'
+        );
+        // // 先取 上次上课声部,在取班级声部 最后取缓存
+        let instrumentId = null;
+        let index = -1;
+        if (forms.courseScheduleSubjectId) {
+          // 判断浏览器上面是否有
+          index = instrumentsList.findIndex(
+            (subject: any) => subject.id == forms.courseScheduleSubjectId
+          );
+          if (index >= 0) {
+            instrumentId = Number(forms.courseScheduleSubjectId);
+          }
+        }
+        // 判断班级上面声部 & 还没有声部
+        if (forms.instrumentId && !instrumentId) {
+          // 判断浏览器上面是否有
+          index = instrumentsList.findIndex(
+            (subject: any) => subject.id == forms.instrumentId
+          );
+          if (index >= 0) {
+            instrumentId = Number(forms.instrumentId);
+          }
+        }
+        // 缓存声部 & 还没有声部
+        if (localStorageSubjectId && !instrumentId) {
+          // 判断浏览器上面是否有
+          index = instrumentsList.findIndex(
+            (subject: any) => subject.id == localStorageSubjectId
+          );
+          if (index >= 0) {
+            instrumentId = Number(localStorageSubjectId);
+          }
+        }
+        // 判断是否选择为空
+        if (instrumentId && index >= 0) {
+          prepareStore.setSubjectId(instrumentId);
+          // forms.instrumentId = instrumentId;
+        } else {
+          // 判断是否有缓存
+          // prepareStore.setSubjectId(instrumentsList[0].id);
+          // forms.instrumentId = instrumentsList[0].id;
+        }
+
+        // 保存
+        localStorage.setItem(
+          'prepareLessonSubjectId',
+          prepareStore.getInstrumentId as any
+        );
+
+        subjectRef.value?.syncBarPosition();
+      }
+    };
+
+    const getInitInstrumentId = () => {
+      let instrumentId: any = '';
+      prepareStore.getInstrumentList.forEach((item: any) => {
+        if (Array.isArray(item.instruments)) {
+          item.instruments.forEach((child: any) => {
+            if (child.id === prepareStore.getInstrumentId) {
+              instrumentId = child.id;
+            }
+          });
+        }
+      });
+      if (instrumentId) {
+        forms.wikiCategoryIdChild = instrumentId;
+      }
+    };
+    const subjectRef = ref();
+    onMounted(async () => {
+      useResizeObserver(
+        document.querySelector('#presetsLeftRef') as HTMLElement,
+        (entries: any) => {
+          const entry = entries[0];
+          const { width } = entry.contentRect;
+          forms.leftWidth = width + 'px';
+        }
+      );
+      useResizeObserver(
+        document.querySelector('#presetsRightRef') as HTMLElement,
+        (entries: any) => {
+          const entry = entries[0];
+          const { width } = entry.contentRect;
+          forms.rightWidth = width + 'px';
+        }
+      );
+
+      prepareStore.setClassGroupId(route.query.classGroupId as any);
+      if (!prepareStore.getInstrumentId) {
+        // 获取教材分类列表
+        checkInstrumentIds();
+      } else {
+        getInitInstrumentId();
+      }
+
+      await getCoursewareList();
+
+      if (props.addParam.isAdd) {
+        forms.addVisiable = true;
+      }
+    });
+
+    // 删除
+    const onRemove = async () => {
+      forms.messageLoading = true;
+      try {
+        await api_teacherChapterLessonCoursewareRemove({
+          id: forms.selectItem.id
+        });
+        message.success('删除成功');
+        getCoursewareList();
+        // getOpenCoursewareList();
+        eventGlobal.emit('openCoursewareChanged');
+        forms.preRemoveVisiable = false;
+      } catch {
+        //
+      }
+      setTimeout(() => {
+        forms.messageLoading = false;
+      }, 100);
+    };
+
+    // 添加课件
+    const onAddCourseware = async (item: any) => {
+      if (forms.messageLoading) return;
+      forms.messageLoading = true;
+      try {
+        await api_addByOpenCourseware({ id: item.id });
+        message.success('添加成功');
+        getCoursewareList();
+        // getOpenCoursewareList();
+        eventGlobal.emit('openCoursewareChanged');
+      } catch {
+        //
+      }
+      setTimeout(() => {
+        forms.messageLoading = false;
+      }, 100);
+    };
+
+    // 预览上课
+    const onPreviewAttend = (id: string) => {
+      // 判断是否在应用里面
+      if (window.matchMedia('(display-mode: standalone)').matches) {
+        state.application = window.matchMedia(
+          '(display-mode: standalone)'
+        ).matches;
+        forms.previewModal = true;
+        fscreen();
+        forms.previewParams = {
+          type: 'preview',
+          courseId: id,
+          instrumentId: prepareStore.getInstrumentId,
+          detailId: prepareStore.getSelectKey,
+          lessonCourseId: prepareStore.getBaseCourseware.id
+        };
+      } else {
+        const { href } = router.resolve({
+          path: '/attend-class',
+          query: {
+            type: 'preview',
+            courseId: id,
+            instrumentId: prepareStore.getInstrumentId,
+            detailId: prepareStore.getSelectKey,
+            lessonCourseId: prepareStore.getBaseCourseware.id
+          }
+        });
+        window.open(href, +new Date() + '');
+      }
+    };
+
+    const onStartClass = async (
+      item: any,
+      classGroupId: any,
+      instrumentId?: any
+    ) => {
+      if (classGroupId) {
+        // 开始上课
+        const res = await courseScheduleStart({
+          lessonCoursewareKnowledgeDetailId: prepareStore.selectKey,
+          classGroupId: classGroupId,
+          useChapterLessonCoursewareId: item.id
+          // instrumentId: prepareStore.getInstrumentId
+        });
+        if (window.matchMedia('(display-mode: standalone)').matches) {
+          state.application = window.matchMedia(
+            '(display-mode: standalone)'
+          ).matches;
+          forms.previewModal = true;
+          fscreen();
+          forms.previewParams = {
+            type: 'class',
+            classGroupId: classGroupId,
+            courseId: item.id,
+            instrumentId: instrumentId || route.query.instrumentId,
+            detailId: prepareStore.getSelectKey,
+            classId: res.data,
+            lessonCourseId: prepareStore.getBaseCourseware.id,
+            preStudentNum: forms.preStudentNum
+          };
+        } else {
+          const { href } = router.resolve({
+            path: '/attend-class',
+            query: {
+              type: 'class',
+              classGroupId: classGroupId,
+              courseId: item.id,
+              // instrumentId: prepareStore.getInstrumentId,
+              instrumentId: instrumentId || route.query.instrumentId,
+              detailId: prepareStore.getSelectKey,
+              classId: res.data,
+              lessonCourseId: prepareStore.getBaseCourseware.id,
+              preStudentNum: forms.preStudentNum
+            }
+          });
+          window.open(href, +new Date() + '');
+        }
+      } else {
+        forms.showAttendClass = true;
+        forms.attendClassType = 'change';
+        forms.attendClassItem = item;
+      }
+    };
+
+    const selectChildObj = (item: any) => {
+      const obj: any = {};
+      item?.forEach((child: any) => {
+        if (child.id === forms.wikiCategoryIdChild) {
+          obj.selected = true;
+          obj.name = child.name;
+          obj.label = child.name;
+        }
+      });
+      return obj;
+    };
+
+    const tabInstrumentValue = computed(() => {
+      let instrumentId: any = prepareStore.getInstrumentId
+        ? prepareStore.getInstrumentId
+        : '';
+      prepareStore.getFormatInstrumentList.forEach((item: any) => {
+        if (Array.isArray(item.instruments)) {
+          item.instruments.forEach((child: any) => {
+            if (child.id === prepareStore.getInstrumentId) {
+              instrumentId = item.id + '';
+            }
+          });
+        }
+      });
+      return instrumentId;
+    });
+    return () => (
+      <div
+        class={[
+          styles.coursewarePresetsContainer,
+          forms.openTableShow && styles.rightLineShow
+        ]}>
+        <div
+          class={styles.presetsLeft}
+          id="presetsLeftRef"
+          style={{ width: `calc(${forms.leftWidth} - ${forms.rightWidth})` }}>
+          <NTabs
+            ref={subjectRef}
+            defaultValue=""
+            paneClass={styles.paneTitle}
+            justifyContent="start"
+            paneWrapperClass={styles.paneWrapperContainer}
+            value={tabInstrumentValue.value}
+            onUpdate:value={(val: any) => {
+              console.log(val, 'item.id', prepareStore.getFormatInstrumentList);
+              prepareStore.getFormatInstrumentList.forEach((item: any) => {
+                if (item.value.toString() === val.toString()) {
+                  prepareStore.setInstrumentId(val);
+                  // 保存
+                  forms.instrumentId = val;
+                  forms.wikiCategoryIdChild = null;
+                }
+              });
+
+              if (!val) {
+                prepareStore.setInstrumentId(val);
+                // 保存
+                forms.instrumentId = val;
+                forms.wikiCategoryIdChild = null;
+                sessionStorage.setItem(
+                  'prepareLessonCourseWareSubjectIsNull',
+                  val ? 'false' : 'true'
+                );
+              }
+            }}
+            v-slots={{
+              suffix: () => (
+                <NButton
+                  class={styles.addBtn}
+                  type="primary"
+                  bordered={false}
+                  onClick={() => {
+                    eventGlobal.emit('teacher-slideshow', true);
+                    emit('change', {
+                      status: true,
+                      type: 'create'
+                    });
+                  }}>
+                  <NImage
+                    class={styles.addBtnIcon}
+                    previewDisabled
+                    src={add}></NImage>
+                  创建课件
+                </NButton>
+              )
+            }}>
+            {[
+              { name: '全部乐器', id: '', label: '全部乐器', value: '' },
+              ...prepareStore.getFormatInstrumentList
+            ].map((item: any, index: number) => (
+              <NTabPane
+                name={`${item.value}`}
+                tab={item.label}
+                disabled={item.instruments?.length > 0}
+                displayDirective="if">
+                {{
+                  tab: () =>
+                    item.instruments?.length > 0 ? (
+                      <NPopselect
+                        options={item.instruments}
+                        trigger="hover"
+                        v-model:value={forms.wikiCategoryIdChild}
+                        onUpdate:value={(val: any) => {
+                          // onSearch();
+                          prepareStore.setInstrumentId(val);
+                          // 保存
+                          forms.instrumentId = val;
+
+                          if (!val) {
+                            sessionStorage.setItem(
+                              'prepareLessonCourseWareSubjectIsNull',
+                              val ? 'false' : 'true'
+                            );
+                          }
+                        }}
+                        key={item.id}
+                        class={styles.popSelect}>
+                        <span
+                          class={[
+                            styles.textBtn,
+                            selectChildObj(item.instruments).selected &&
+                              styles.textBtnActive
+                          ]}>
+                          {selectChildObj(item.instruments).label || item.label}
+                          <i class={styles.iconArrow}></i>
+                        </span>
+                      </NPopselect>
+                    ) : (
+                      item.label
+                    )
+                }}
+              </NTabPane>
+            ))}
+          </NTabs>
+          <NSpin show={forms.loading}>
+            <NScrollbar class={styles.coursewarePresets}>
+              <div style={{ overflow: 'hidden' }}>
+                <div
+                  class={[
+                    styles.list,
+                    !forms.loading &&
+                      forms.tableList.length <= 0 &&
+                      styles.listEmpty
+                  ]}>
+                  {forms.tableList.map((item: any) => (
+                    <div class={[styles.itemWrap, styles.itemBlock, 'row-nav']}>
+                      <div class={styles.itemWrapBox}>
+                        <CoursewareType
+                          operate
+                          isEditName
+                          item={item}
+                          onClick={() => onPreviewAttend(item.id)}
+                          // onEditName={() => {
+                          //   forms.selectItem = item;
+                          //   forms.editTitle = item.name;
+                          //   forms.editTitleVisiable = true;
+                          // }}
+                          onEdit={() => {
+                            //
+                            eventGlobal.emit('teacher-slideshow', true);
+                            emit('change', {
+                              status: true,
+                              type: 'update',
+                              groupItem: { id: item.id }
+                            });
+                          }}
+                          onStartClass={() =>
+                            onStartClass(item, forms.classGroupId)
+                          }
+                          onDelete={() => {
+                            forms.selectItem = item;
+                            forms.preRemoveVisiable = true;
+                          }}
+                          // 布置作业
+                          onWork={() => {
+                            forms.workVisiable = true;
+                            forms.selectItem = item;
+                          }}
+                        />
+                      </div>
+                    </div>
+                  ))}
+                  {!forms.loading && forms.tableList.length <= 0 && (
+                    <TheEmpty
+                      class={styles.empty1}
+                      description="当前章节暂无课件,快点击右上角创建课件吧"
+                    />
+                  )}
+                </div>
+              </div>
+            </NScrollbar>
+          </NSpin>
+        </div>
+
+        <div class={styles.presetsRight} id="presetsRightRef">
+          <NTooltip showArrow={false} animated={false} duration={0} delay={0}>
+            {{
+              trigger: () => (
+                <div
+                  class={[
+                    styles.presetsArrar,
+                    !forms.openTableShow && styles.presetsArrarActive
+                  ]}
+                  onClick={() => (forms.openTableShow = !forms.openTableShow)}>
+                  <NIcon>
+                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+                      <path
+                        d="M16.62 2.99a1.25 1.25 0 0 0-1.77 0L6.54 11.3a.996.996 0 0 0 0 1.41l8.31 8.31c.49.49 1.28.49 1.77 0s.49-1.28 0-1.77L9.38 12l7.25-7.25c.48-.48.48-1.28-.01-1.76z"
+                        fill="currentColor"></path>
+                    </svg>
+                  </NIcon>
+                </div>
+              ),
+              default: () => <div>{forms.openTableShow ? '收起' : '展开'}</div>
+            }}
+          </NTooltip>
+
+          <Related
+            onMore={() => (forms.showRelatedClass = true)}
+            onAdd={(item: any) => {
+              onAddCourseware(item);
+            }}
+            onLook={(item: any) => {
+              onPreviewAttend(item.id);
+            }}
+          />
+        </div>
+        {/* )} */}
+
+        <NModal
+          v-model:show={forms.showRelatedClass}
+          preset="card"
+          showIcon={false}
+          class={['modalTitle background', styles.attendClassModal1]}
+          title={'相关课件'}
+          blockScroll={false}>
+          <RelatedClass
+            tableList={forms.tableList}
+            instrumentList={prepareStore.getInstrumentList}
+            instrumentId={prepareStore.getInstrumentId as any}
+            coursewareDetailKnowledgeId={prepareStore.getSelectKey}
+            onClose={() => (forms.showRelatedClass = false)}
+            onAdd={(item: any) => onAddCourseware(item)}
+            onClick={(item: any) => {
+              onPreviewAttend(item.id);
+              forms.showRelatedClass = false;
+            }}
+          />
+        </NModal>
+
+        {/* <NModal
+          v-model:show={forms.editTitleVisiable}
+          preset="card"
+          class={['modalTitle', styles.removeVisiable1]}
+          title={'课件重命名'}>
+          <div class={styles.studentRemove}>
+            <NInput
+              placeholder="请输入课件名称"
+              v-model:value={forms.editTitle}
+              maxlength={15}
+              onKeyup={(e: any) => {
+                if (e.code === 'ArrowLeft' || e.code === 'ArrowRight') {
+                  e.stopPropagation();
+                }
+              }}
+            />
+
+            <NSpace class={styles.btnGroupModal} justify="center">
+              <NButton round onClick={() => (forms.editTitleVisiable = false)}>
+                取消
+              </NButton>
+              <NButton
+                round
+                type="primary"
+                onClick={onEditTitleSubmit}
+                loading={forms.editBtnLoading}>
+                确定
+              </NButton>
+            </NSpace>
+          </div>
+        </NModal> */}
+
+        <NModal
+          v-model:show={forms.preRemoveVisiable}
+          preset="card"
+          class={['modalTitle', styles.removeVisiable1]}
+          title={'删除课件'}>
+          <TheMessageDialog
+            content={`<p style="text-align: left;">请确认是否删除【${forms.selectItem.name}】,删除后不可恢复</p>`}
+            cancelButtonText="取消"
+            confirmButtonText="确认"
+            loading={forms.messageLoading}
+            onClose={() => (forms.preRemoveVisiable = false)}
+            onConfirm={() => onRemove()}
+          />
+        </NModal>
+
+        <NModal
+          v-model:show={forms.addVisiable}
+          preset="card"
+          class={['modalTitle', styles.removeVisiable1]}
+          title={'保存成功'}>
+          <TheMessageDialog
+            content={`<p style="text-align: left;">【${props.addParam.name}】暂未设置课件作业,是否现在去设置课件作业</p>`}
+            cancelButtonText="稍后设置"
+            confirmButtonText="立即设置"
+            // loading={forms.messageLoading}
+            onClose={() => (forms.addVisiable = false)}
+            onConfirm={() => {
+              forms.addVisiable = false;
+              forms.workVisiable = true;
+              forms.selectItem = {
+                id: props.addParam.id,
+                name: props.addParam.name
+              };
+            }}
+          />
+        </NModal>
+
+        {/* 应用内预览或上课 */}
+        <PreviewWindow
+          v-model:show={forms.previewModal}
+          type="attend"
+          params={forms.previewParams}
+        />
+
+        <NModal
+          v-model:show={forms.showAttendClass}
+          preset="card"
+          showIcon={false}
+          class={['modalTitle background', styles.attendClassModal]}
+          title={'选择班级'}
+          blockScroll={false}>
+          <AttendClass
+            onClose={() => (forms.showAttendClass = false)}
+            type={forms.attendClassType}
+            onPreview={(item: any) => {
+              if (window.matchMedia('(display-mode: standalone)').matches) {
+                state.application = window.matchMedia(
+                  '(display-mode: standalone)'
+                ).matches;
+                forms.previewModal = true;
+                forms.previewParams = {
+                  ...item
+                };
+              } else {
+                const { href } = router.resolve({
+                  path: '/attend-class',
+                  query: {
+                    ...item
+                  }
+                });
+                window.open(href, +new Date() + '');
+              }
+            }}
+            onConfirm={async (item: any) => {
+              onStartClass(
+                forms.attendClassItem,
+                item.classGroupId,
+                item.instrumentId
+              );
+            }}
+          />
+        </NModal>
+
+        <NModal
+          v-model:show={forms.workVisiable}
+          preset="card"
+          class={['modalTitle background', styles.workVisiable]}
+          title={
+            forms.selectItem.lessonPreTrainingId ? '编辑作业' : '创建作业'
+          }>
+          <div id="model-homework-height" class={styles.workContainer}>
+            <div class={styles.workTrain}>
+              <Train
+                cardType="prepare"
+                lessonPreTraining={{
+                  title: forms.selectItem.name + '-课后作业',
+                  chapterId: forms.selectItem.id, // 课件编号
+                  id: forms.selectItem.lessonPreTrainingId // 作业编号
+                }}
+                onChange={(val: any) => {
+                  forms.workVisiable = val.status;
+                  getCoursewareList();
+                }}
+              />
+            </div>
+            <div class={styles.resourceMain}>
+              <ResourceMain cardType="prepare" />
+            </div>
+          </div>
+        </NModal>
+      </div>
+    );
+  }
+});

+ 133 - 129
src/views/prepare-lessons/components/lesson-main/index.module.less

@@ -1,130 +1,134 @@
-.coursewareSection {
-  display: flex;
-  height: 100%;
-
-  .coursewareHeader {
-    flex: 0 0 360px;
-    background-color: #fff;
-    border-radius: 20px;
-
-    padding-bottom: 40px;
-  }
-
-  .lesson-main {
-    flex: 1;
-    margin-left: 20px
-  }
-
-  :global {
-    .listContainerWrap {
-      max-height: calc(var(--window-page-lesson-height) - 40px - 20px);
-
-      .listSectionWrap {
-        min-height: calc(var(--window-page-lesson-height) - 40px - 20px);
-      }
-    }
-  }
-}
-
-:global {
-  .listContainerResource {
-    max-height: calc(var(--window-page-lesson-height) - 244px - 100px) !important;
-    // overflow-x: auto;
-
-    &.listNoMusicResource {
-      max-height: calc(var(--window-page-lesson-height) - 184px - 100px) !important;
-
-      .listSectionResource {
-        min-height: calc(var(--window-page-lesson-height) - 184px - 100px) !important;
-      }
-    }
-
-    .listSectionResource {
-      min-height: calc(var(--window-page-lesson-height) - 204px - 100px) !important;
-    }
-  }
-}
-
-.lesson-main {
-  height: 100%;
-  background-color: #fff;
-  border-radius: 20px;
-
-  :global {
-    .n-tabs-tab-pad {
-      width: 64px !important;
-    }
-
-    .n-tabs-nav {
-      padding: 12px 20px 20px;
-    }
-
-    .n-tabs-tab {
-      color: #8B8D98;
-      font-size: max(20px, 14Px);
-      padding-top: 12px;
-      padding-bottom: 8px;
-      line-height: 28px;
-
-      &.n-tabs-tab--active {
-        font-weight: 600 !important;
-        color: #131415 !important;
-      }
-    }
-
-    .n-tabs-tab__label {
-      z-index: 10;
-    }
-
-    .n-tabs-bar {
-      height: 10px;
-      background: linear-gradient(90deg, #77BBFF 0%, rgba(163, 231, 255, 0.22) 100%);
-      z-index: 0;
-      bottom: 8px;
-      transition-duration: 0.03;
-    }
-
-    .n-tab-pane {
-      padding-top: 4px !important;
-    }
-  }
-}
-
-.coursewareFooter {
-  position: absolute;
-  bottom: 0;
-  left: 100px;
-  right: 0;
-  z-index: 100;
-  background: #FFFFFF;
-  box-shadow: 0 2px 10px 0px rgba(0, 0, 0, 0.12);
-  height: 68px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-
-  :global {
-    .n-button {
-      border-radius: 8px;
-      height: 42px;
-      font-size: max(18px, 14Px);
-      font-weight: 600 !important;
-      padding: 0 32px;
-    }
-
-    .n-button--error-type {
-      background: #FDEBED !important;
-      color: #EC3A4E !important;
-
-      &:not(.n-button--disabled):hover,
-      &:not(.n-button--disabled):active {
-        background: #FDEFF0;
-        color: #EF6171;
-      }
-
-      .n-button__border {
-        border: 1px solid #EC3A4E;
-      }
-    }
-  }
+.coursewareSection {
+  display: flex;
+  height: 100%;
+
+  .coursewareHeader {
+    flex: 0 0 360px;
+    background-color: #fff;
+    border-radius: 20px;
+
+    padding-bottom: 40px;
+  }
+
+  .lesson-main {
+    flex: 1;
+    margin-left: 20px
+  }
+
+  :global {
+    .listContainerWrap {
+      max-height: calc(var(--window-page-lesson-height) - 40px - 20px);
+
+      .listSectionWrap {
+        min-height: calc(var(--window-page-lesson-height) - 40px - 20px);
+      }
+    }
+  }
+}
+
+:global {
+  .listContainerResource {
+    max-height: calc(var(--window-page-lesson-height) - 244px - 100px) !important;
+    // overflow-x: auto;
+
+    &.listNoMusicResource {
+      max-height: calc(var(--window-page-lesson-height) - 184px - 100px) !important;
+
+      .listSectionResource {
+        min-height: calc(var(--window-page-lesson-height) - 184px - 100px) !important;
+      }
+    }
+
+    .listSectionResource {
+      min-height: calc(var(--window-page-lesson-height) - 204px - 100px) !important;
+    }
+  }
+}
+
+.lesson-main {
+  height: 100%;
+  background-color: #fff;
+  border-radius: 20px;
+
+  :global {
+    .n-tabs-tab-pad {
+      width: 64px !important;
+    }
+
+    .n-tabs-nav {
+      padding: 12px 20px 20px;
+    }
+
+    .n-tabs-tab {
+      color: #8B8D98;
+      font-size: max(20px, 14Px);
+      padding-top: 12px;
+      padding-bottom: 8px;
+      line-height: 28px;
+
+      &.n-tabs-tab--active {
+        font-weight: 600 !important;
+        color: #131415 !important;
+      }
+    }
+
+    .n-tabs-tab__label {
+      z-index: 10;
+    }
+
+    .n-tabs-bar {
+      height: 10px;
+      background: linear-gradient(90deg, #77BBFF 0%, rgba(163, 231, 255, 0.22) 100%);
+      z-index: 0;
+      bottom: 8px;
+      transition-duration: 0.03;
+    }
+
+    .n-tabs-bar--disabled {
+      background-color: #fff !important;
+    }
+
+    .n-tab-pane {
+      padding-top: 4px !important;
+    }
+  }
+}
+
+.coursewareFooter {
+  position: absolute;
+  bottom: 0;
+  left: 100px;
+  right: 0;
+  z-index: 100;
+  background: #FFFFFF;
+  box-shadow: 0 2px 10px 0px rgba(0, 0, 0, 0.12);
+  height: 68px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+
+  :global {
+    .n-button {
+      border-radius: 8px;
+      height: 42px;
+      font-size: max(18px, 14Px);
+      font-weight: 600 !important;
+      padding: 0 32px;
+    }
+
+    .n-button--error-type {
+      background: #FDEBED !important;
+      color: #EC3A4E !important;
+
+      &:not(.n-button--disabled):hover,
+      &:not(.n-button--disabled):active {
+        background: #FDEFF0;
+        color: #EF6171;
+      }
+
+      .n-button__border {
+        border: 1px solid #EC3A4E;
+      }
+    }
+  }
 }

+ 502 - 494
src/views/prepare-lessons/model/courseware-type/index.module.less

@@ -1,495 +1,503 @@
-.coursewareType {
-  position: relative;
-  border-radius: 13px;
-  padding: 10px 10px 0;
-  transition: all .2s ease;
-
-  &:hover {
-    background: #FFFFFF;
-    box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1);
-    border-radius: 15px;
-    transition: all .2s ease;
-
-    &:hover .footer {
-      opacity: 1;
-      visibility: visible;
-      transition: all .2s ease;
-    }
-  }
-
-  &.coursewareTypeHover:hover {
-    .addBtn {
-      opacity: 1;
-      visibility: visible;
-    }
-  }
-
-  &.coursewareTypeHocoursewareTypeShow {
-    // .cover {
-    //   cursor: default;
-    // }
-
-    .addBtn {
-      opacity: 1;
-      visibility: visible;
-    }
-  }
-
-  .addBtn {
-    opacity: 0;
-    visibility: hidden;
-    position: absolute;
-    top: 15px;
-    right: 15px;
-    // width: 60px;
-    height: 27px;
-    background: #3D9EFF;
-    border-radius: 5px;
-    padding: 0 12px;
-
-    z-index: 1;
-    --n-border: none !important;
-    font-size: max(16px, 12Px) !important;
-  }
-
-  :global {
-    .n-button.n-button--disabled {
-      background: #ccc;
-      --n-border-disabled: none !important;
-    }
-  }
-
-  .cover {
-    cursor: pointer;
-    position: relative;
-    height: 153px;
-    border-radius: 10px;
-    overflow: hidden;
-    background-color: #fff;
-    border: 1px solid #EFF0F2;
-    transition: all .2s ease;
-
-    &:hover {
-      :global {
-        .n-image {
-          transform: scale(1.05);
-          transition: all 0.2s ease;
-          // &:hover {
-          // }
-        }
-      }
-
-      .defaultLook {
-        opacity: 1;
-        visibility: visible;
-      }
-    }
-
-    .defaultLook {
-      position: absolute;
-      opacity: 0;
-      visibility: hidden;
-      inset: 0;
-      background-color: rgba(0, 0, 0, 0.3);
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      cursor: pointer;
-      transition: all 0.2s ease;
-
-      &::before {
-        display: inline-block;
-        content: '';
-        width: 25px;
-        height: 25px;
-        background: url('../../images/icon-look.png') no-repeat center;
-        background-size: contain;
-      }
-    }
-
-    // 布置作业
-    &.isShowAdd:hover {
-      .defaultLook {
-        display: none;
-      }
-
-      .function {
-        opacity: 1;
-        visibility: visible;
-        transition: all .1s ease;
-      }
-    }
-
-    .iconNoWork {
-      position: absolute;
-      right: 0;
-      top: 0;
-      display: inline-block;
-      width: 97px;
-      height: 26px;
-      background: url('../../images/icon-no-work.png') no-repeat center;
-      background-size: contain;
-    }
-
-    .status {
-      position: absolute;
-      top: 7px;
-      left: 7px;
-      background: linear-gradient(226deg, #13BFFF 0%, #1183FF 100%);
-      border-radius: 4px;
-      font-weight: 600;
-      font-size: max(12px, 11Px);
-      color: #FFFFFF;
-      padding: 3px 10px;
-      z-index: 9;
-    }
-
-    :global {
-      .n-image {
-        width: 100%;
-        height: 100%;
-        transition: all 0.2s ease;
-      }
-    }
-
-    img {
-      width: 100%;
-      height: fit-content;
-    }
-
-    &.hideP:hover {
-      &::after {
-        display: none;
-      }
-
-      .preview {
-        opacity: 1;
-        visibility: visible;
-        transition: all .2s ease;
-      }
-    }
-  }
-
-
-  .preview {
-    position: absolute;
-    opacity: 0;
-    visibility: hidden;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    background-color: rgba(0, 0, 0, 0.3);
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
-    cursor: pointer;
-
-    .previewBtn {
-      background: #3D9EFF;
-      height: max(40px, 32Px);
-      padding: 0 30px;
-      border-radius: 12px;
-      color: #fff;
-    }
-  }
-
-  .coursewareText {
-    padding: 10px 0 0;
-
-    .name {
-      font-weight: 600;
-      font-size: max(14px, 13Px);
-      color: #000000;
-      display: flex;
-      align-items: center;
-
-      span {
-        list-style: 16Px;
-        max-width: 100%;
-        display: inline-block;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        white-space: nowrap;
-      }
-
-      .iconEditName {
-        display: none;
-        width: max(13px, 12Px);
-        height: max(13px, 12Px);
-        background: url('../../images/icon-edit-name.png') no-repeat center center;
-        background-size: contain;
-      }
-    }
-
-    .subjectName {
-      max-width: 100%;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-    }
-
-    .editName {
-      display: flex;
-      align-items: center;
-      // justify-content: space-between;
-
-      span {
-        max-width: 94%;
-      }
-
-      &:hover {
-        span {
-          // color: #1677FF;
-        }
-
-        .iconEditName {
-          margin-left: 6px;
-          cursor: pointer;
-          flex-shrink: 0;
-          display: inline-block;
-        }
-      }
-    }
-
-    .subjectName {
-      padding-top: 5px;
-      font-size: 11Px;
-      color: #777777;
-      line-height: 16Px;
-    }
-  }
-}
-
-.operationBottom {
-  padding-bottom: 16px;
-
-
-}
-
-
-.footer {
-  opacity: 0;
-  visibility: hidden;
-  display: flex;
-  align-items: center;
-  padding-top: 10px;
-  padding-bottom: 8px;
-  position: absolute;
-  left: 10px;
-  right: 10px;
-  bottom: 12px;
-  background-color: #fff;
-  transition: all .2s ease;
-
-  :global {
-    .n-space {
-      gap: 8px 10px !important;
-    }
-  }
-
-  .actionClass {
-    cursor: pointer;
-    flex: 1;
-    height: 30Px !important;
-    line-height: 30Px;
-    background: #198CFE;
-    border-radius: 7px;
-    text-align: center;
-    margin-right: 10px;
-    font-size: max(14px, 13Px);
-    color: #fff;
-    font-weight: 600;
-    transition: all .2s ease;
-
-    &:hover {
-      background-color: rgba(25, 140, 254, 0.8);
-      transition: all .2s ease;
-      // color: #fff;
-    }
-
-    &.actionWork {
-      margin-right: 0;
-      background: rgba(245, 246, 250, 1);
-      color: #484F59;
-      padding: 0 13px;
-
-      &:hover {
-        background-color: rgba(245, 246, 250, 1);
-        color: rgba(25, 140, 254, 1);
-      }
-    }
-  }
-
-  .menu {
-    height: 30Px !important;
-    line-height: 30Px;
-    width: 30Px !important;
-    background: rgba(245, 246, 250, 1);
-    border-radius: 7px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    cursor: pointer;
-
-    &::after {
-      content: '';
-      display: inline-block;
-      width: 13Px;
-      height: 10Px;
-      background: url('../../images/icon-menu-default.png') no-repeat center;
-      background-size: contain;
-    }
-
-    &:hover {
-      &::after {
-        background: url('../../images/icon-menu-active.png') no-repeat center;
-        background-size: contain;
-      }
-    }
-  }
-
-
-  // .optons {
-  //   width: 20Px;
-  //   height: 20Px;
-  //   background: #FFFFFF;
-  //   border-radius: 7px;
-  //   padding: 5px;
-  //   box-sizing: content-box;
-  //   cursor: pointer;
-  //   display: flex;
-  //   align-items: center;
-  //   justify-content: center;
-
-  //   img {
-  //     width: 20Px;
-  //     height: 20Px;
-  //   }
-
-  //   .iconEdit,
-  //   .iconDelete {
-  //     display: inline-block;
-  //     width: 24px;
-  //     height: 24px;
-  //   }
-
-  //   .iconEdit {
-  //     background: url('../../images/icon-courseware-edit.png') no-repeat center;
-  //     background-size: contain;
-  //   }
-
-  //   .iconDelete {
-  //     background: url('../../images/icon-courseware-delete.png') no-repeat center;
-  //     background-size: contain;
-  //   }
-
-  //   // &:hover {
-  //   //   .iconEdit {
-  //   //     background: url('../../images/icon-courseware-edit-active.png') no-repeat center;
-  //   //     background-size: contain;
-  //   //   }
-
-  //   //   .iconDelete {
-  //   //     background: url('../../images/icon-courseware-delete-active.png') no-repeat center;
-  //   //     background-size: contain;
-  //   //   }
-  //   // }
-  // }
-  .iconEdit,
-  .iconDelete {
-    display: inline-block;
-    width: 24px;
-    height: 24px;
-  }
-
-  .iconEdit {
-    background: url('../../images/icon-courseware-edit.png') no-repeat center;
-    background-size: contain;
-  }
-
-  .iconDelete {
-    background: url('../../images/icon-courseware-delete.png') no-repeat center;
-    background-size: contain;
-  }
-
-  .popoverItem {
-    display: flex;
-    align-items: center;
-    font-weight: 600;
-    font-size: max(13px, 12Px);
-    color: #484F59;
-    line-height: 18px;
-    border-radius: 8px;
-    padding: 8px 13px;
-    cursor: pointer;
-    margin: 3px 0;
-
-    i {
-      margin-right: 13px;
-    }
-
-    &:hover {
-      background: #F5F6FA;
-    }
-  }
-
-  :global {
-    .n-popover {
-      box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.1);
-      border-radius: 10px;
-      padding: 9px 7px !important;
-    }
-  }
-}
-
-.function {
-  position: absolute;
-  inset: 0;
-  background: rgba(0, 0, 0, .3);
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  opacity: 0;
-  visibility: hidden;
-  transition: opacity 0.1s ease;
-
-  .iconLook,
-  .iconAdd {
-    cursor: pointer;
-    width: 38px;
-    height: 38px;
-    border-radius: 50%;
-    background: rgba(0, 0, 0, .4);
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    margin: 0 16px;
-
-  }
-
-  .iconLook {
-    &::before {
-      display: inline-block;
-      content: '';
-      width: 25px;
-      height: 25px;
-      background: url('../../images/icon-look.png') no-repeat center;
-      background-size: contain;
-    }
-  }
-
-
-  .iconAdd {
-    &::before {
-      display: inline-block;
-      content: '';
-      width: 18px;
-      height: 18px;
-      background: url('../../images/icon-add.png') no-repeat center;
-      background-size: contain;
-    }
-  }
-
+.coursewareType {
+  position: relative;
+  border-radius: 13px;
+  padding: 10px 10px 0;
+  transition: all .2s ease;
+
+  &:hover {
+    background: #FFFFFF;
+    box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1);
+    border-radius: 15px;
+    transition: all .2s ease;
+
+    &:hover .footer {
+      opacity: 1;
+      visibility: visible;
+      transition: all .2s ease;
+    }
+  }
+
+  &.coursewareTypeHover:hover {
+    .addBtn {
+      opacity: 1;
+      visibility: visible;
+    }
+  }
+
+  &.coursewareTypeHocoursewareTypeShow {
+    // .cover {
+    //   cursor: default;
+    // }
+
+    .addBtn {
+      opacity: 1;
+      visibility: visible;
+    }
+  }
+
+  .addBtn {
+    opacity: 0;
+    visibility: hidden;
+    position: absolute;
+    top: 15px;
+    right: 15px;
+    // width: 60px;
+    height: 27px;
+    background: #3D9EFF;
+    border-radius: 5px;
+    padding: 0 12px;
+
+    z-index: 1;
+    --n-border: none !important;
+    font-size: max(16px, 12Px) !important;
+  }
+
+  :global {
+    .n-button.n-button--disabled {
+      background: #ccc;
+      --n-border-disabled: none !important;
+    }
+  }
+
+  .cover {
+    cursor: pointer;
+    position: relative;
+    height: 153px;
+    border-radius: 10px;
+    overflow: hidden;
+    background-color: #fff;
+    border: 1px solid #EFF0F2;
+    transition: all .2s ease;
+
+    .noCoverImg {
+      background-color: #000;
+
+      img {
+        display: none;
+      }
+    }
+
+    &:hover {
+      :global {
+        .n-image {
+          transform: scale(1.05);
+          transition: all 0.2s ease;
+          // &:hover {
+          // }
+        }
+      }
+
+      .defaultLook {
+        opacity: 1;
+        visibility: visible;
+      }
+    }
+
+    .defaultLook {
+      position: absolute;
+      opacity: 0;
+      visibility: hidden;
+      inset: 0;
+      background-color: rgba(0, 0, 0, 0.3);
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      cursor: pointer;
+      transition: all 0.2s ease;
+
+      &::before {
+        display: inline-block;
+        content: '';
+        width: 25px;
+        height: 25px;
+        background: url('../../images/icon-look.png') no-repeat center;
+        background-size: contain;
+      }
+    }
+
+    // 布置作业
+    &.isShowAdd:hover {
+      .defaultLook {
+        display: none;
+      }
+
+      .function {
+        opacity: 1;
+        visibility: visible;
+        transition: all .1s ease;
+      }
+    }
+
+    .iconNoWork {
+      position: absolute;
+      right: 0;
+      top: 0;
+      display: inline-block;
+      width: 97px;
+      height: 26px;
+      background: url('../../images/icon-no-work.png') no-repeat center;
+      background-size: contain;
+    }
+
+    .status {
+      position: absolute;
+      top: 7px;
+      left: 7px;
+      background: linear-gradient(226deg, #13BFFF 0%, #1183FF 100%);
+      border-radius: 4px;
+      font-weight: 600;
+      font-size: max(12px, 11Px);
+      color: #FFFFFF;
+      padding: 3px 10px;
+      z-index: 9;
+    }
+
+    :global {
+      .n-image {
+        width: 100%;
+        height: 100%;
+        transition: all 0.2s ease;
+      }
+    }
+
+    img {
+      width: 100%;
+      height: fit-content;
+    }
+
+    &.hideP:hover {
+      &::after {
+        display: none;
+      }
+
+      .preview {
+        opacity: 1;
+        visibility: visible;
+        transition: all .2s ease;
+      }
+    }
+  }
+
+
+  .preview {
+    position: absolute;
+    opacity: 0;
+    visibility: hidden;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, 0.3);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+    cursor: pointer;
+
+    .previewBtn {
+      background: #3D9EFF;
+      height: max(40px, 32Px);
+      padding: 0 30px;
+      border-radius: 12px;
+      color: #fff;
+    }
+  }
+
+  .coursewareText {
+    padding: 10px 0 0;
+
+    .name {
+      font-weight: 600;
+      font-size: max(14px, 13Px);
+      color: #000000;
+      display: flex;
+      align-items: center;
+
+      span {
+        list-style: 16Px;
+        max-width: 100%;
+        display: inline-block;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+
+      .iconEditName {
+        display: none;
+        width: max(13px, 12Px);
+        height: max(13px, 12Px);
+        background: url('../../images/icon-edit-name.png') no-repeat center center;
+        background-size: contain;
+      }
+    }
+
+    .subjectName {
+      max-width: 100%;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+
+    .editName {
+      display: flex;
+      align-items: center;
+      // justify-content: space-between;
+
+      span {
+        max-width: 94%;
+      }
+
+      &:hover {
+        span {
+          // color: #1677FF;
+        }
+
+        .iconEditName {
+          margin-left: 6px;
+          cursor: pointer;
+          flex-shrink: 0;
+          display: inline-block;
+        }
+      }
+    }
+
+    .subjectName {
+      padding-top: 5px;
+      font-size: 11Px;
+      color: #777777;
+      line-height: 16Px;
+    }
+  }
+}
+
+.operationBottom {
+  padding-bottom: 16px;
+
+
+}
+
+
+.footer {
+  opacity: 0;
+  visibility: hidden;
+  display: flex;
+  align-items: center;
+  padding-top: 10px;
+  padding-bottom: 8px;
+  position: absolute;
+  left: 10px;
+  right: 10px;
+  bottom: 12px;
+  background-color: #fff;
+  transition: all .2s ease;
+
+  :global {
+    .n-space {
+      gap: 8px 10px !important;
+    }
+  }
+
+  .actionClass {
+    cursor: pointer;
+    flex: 1;
+    height: 30Px !important;
+    line-height: 30Px;
+    background: #198CFE;
+    border-radius: 7px;
+    text-align: center;
+    margin-right: 10px;
+    font-size: max(14px, 13Px);
+    color: #fff;
+    font-weight: 600;
+    transition: all .2s ease;
+
+    &:hover {
+      background-color: rgba(25, 140, 254, 0.8);
+      transition: all .2s ease;
+      // color: #fff;
+    }
+
+    &.actionWork {
+      margin-right: 0;
+      background: rgba(245, 246, 250, 1);
+      color: #484F59;
+      padding: 0 13px;
+
+      &:hover {
+        background-color: rgba(245, 246, 250, 1);
+        color: rgba(25, 140, 254, 1);
+      }
+    }
+  }
+
+  .menu {
+    height: 30Px !important;
+    line-height: 30Px;
+    width: 30Px !important;
+    background: rgba(245, 246, 250, 1);
+    border-radius: 7px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+
+    &::after {
+      content: '';
+      display: inline-block;
+      width: 13Px;
+      height: 10Px;
+      background: url('../../images/icon-menu-default.png') no-repeat center;
+      background-size: contain;
+    }
+
+    &:hover {
+      &::after {
+        background: url('../../images/icon-menu-active.png') no-repeat center;
+        background-size: contain;
+      }
+    }
+  }
+
+
+  // .optons {
+  //   width: 20Px;
+  //   height: 20Px;
+  //   background: #FFFFFF;
+  //   border-radius: 7px;
+  //   padding: 5px;
+  //   box-sizing: content-box;
+  //   cursor: pointer;
+  //   display: flex;
+  //   align-items: center;
+  //   justify-content: center;
+
+  //   img {
+  //     width: 20Px;
+  //     height: 20Px;
+  //   }
+
+  //   .iconEdit,
+  //   .iconDelete {
+  //     display: inline-block;
+  //     width: 24px;
+  //     height: 24px;
+  //   }
+
+  //   .iconEdit {
+  //     background: url('../../images/icon-courseware-edit.png') no-repeat center;
+  //     background-size: contain;
+  //   }
+
+  //   .iconDelete {
+  //     background: url('../../images/icon-courseware-delete.png') no-repeat center;
+  //     background-size: contain;
+  //   }
+
+  //   // &:hover {
+  //   //   .iconEdit {
+  //   //     background: url('../../images/icon-courseware-edit-active.png') no-repeat center;
+  //   //     background-size: contain;
+  //   //   }
+
+  //   //   .iconDelete {
+  //   //     background: url('../../images/icon-courseware-delete-active.png') no-repeat center;
+  //   //     background-size: contain;
+  //   //   }
+  //   // }
+  // }
+  .iconEdit,
+  .iconDelete {
+    display: inline-block;
+    width: 24px;
+    height: 24px;
+  }
+
+  .iconEdit {
+    background: url('../../images/icon-courseware-edit.png') no-repeat center;
+    background-size: contain;
+  }
+
+  .iconDelete {
+    background: url('../../images/icon-courseware-delete.png') no-repeat center;
+    background-size: contain;
+  }
+
+  .popoverItem {
+    display: flex;
+    align-items: center;
+    font-weight: 600;
+    font-size: max(13px, 12Px);
+    color: #484F59;
+    line-height: 18px;
+    border-radius: 8px;
+    padding: 8px 13px;
+    cursor: pointer;
+    margin: 3px 0;
+
+    i {
+      margin-right: 13px;
+    }
+
+    &:hover {
+      background: #F5F6FA;
+    }
+  }
+
+  :global {
+    .n-popover {
+      box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.1);
+      border-radius: 10px;
+      padding: 9px 7px !important;
+    }
+  }
+}
+
+.function {
+  position: absolute;
+  inset: 0;
+  background: rgba(0, 0, 0, .3);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  opacity: 0;
+  visibility: hidden;
+  transition: opacity 0.1s ease;
+
+  .iconLook,
+  .iconAdd {
+    cursor: pointer;
+    width: 38px;
+    height: 38px;
+    border-radius: 50%;
+    background: rgba(0, 0, 0, .4);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin: 0 16px;
+
+  }
+
+  .iconLook {
+    &::before {
+      display: inline-block;
+      content: '';
+      width: 25px;
+      height: 25px;
+      background: url('../../images/icon-look.png') no-repeat center;
+      background-size: contain;
+    }
+  }
+
+
+  .iconAdd {
+    &::before {
+      display: inline-block;
+      content: '';
+      width: 18px;
+      height: 18px;
+      background: url('../../images/icon-add.png') no-repeat center;
+      background-size: contain;
+    }
+  }
+
 }

+ 173 - 168
src/views/prepare-lessons/model/courseware-type/index.tsx

@@ -1,168 +1,173 @@
-import { defineComponent } from 'vue';
-import styles from './index.module.less';
-import { NButton, NImage, NPopover, NSpace, NTooltip } from 'naive-ui';
-// import iconEdit from '../../images/icon-courseware-edit.png';
-// import iconDelete from '../../images/icon-courseware-delete.png';
-// import iconEditName from '../../images/icon-edit-name.png';
-
-export default defineComponent({
-  name: 'courseware-type',
-  props: {
-    item: {
-      type: Object,
-      default: () => ({})
-    },
-    /** 是否鼠标滑动时显示显示添加按钮 */
-    isHoverShowAdd: {
-      type: Boolean,
-      default: true
-    },
-    /** 是否显示添加按钮 */
-    isShowAdd: {
-      type: Boolean,
-      default: false
-    },
-    /** 是否支持编辑名称 */
-    isEditName: {
-      type: Boolean,
-      default: false
-    },
-    /** 是否显示操作按钮 */
-    operate: {
-      type: Boolean,
-      default: false
-    },
-    /** 是否显示预览按钮 */
-    isShowPreviewBtn: {
-      type: Boolean,
-      default: false
-    },
-    isShowOpenFlag: {
-      type: Boolean,
-      default: true
-    }
-  },
-  /** add */
-  emits: [
-    'add',
-    'editName',
-    'edit',
-    'delete',
-    'startClass',
-    'click',
-    'work',
-    'look'
-  ],
-  setup(props, { emit }) {
-    return () => (
-      <div
-        class={[
-          styles.coursewareType,
-          props.isHoverShowAdd
-            ? styles.coursewareTypeHover
-            : styles.coursewareTypeHocoursewareTypeShow
-        ]}>
-        <div
-          class={[
-            styles.cover,
-            props.isShowPreviewBtn && styles.hideP,
-            props.isShowAdd && styles.isShowAdd
-          ]}
-          onClick={() => emit('click')}>
-          {props.item.openFlag && props.isShowOpenFlag && (
-            <span class={styles.status}>公开</span>
-          )}
-          <NImage objectFit="cover" previewDisabled src={props.item.coverImg} />
-
-          <i class={styles.defaultLook}></i>
-
-          {props.isShowPreviewBtn && (
-            <div class={styles.preview}>
-              <NButton strong secondary class={styles.previewBtn}>
-                使用课件
-              </NButton>
-            </div>
-          )}
-
-          {/* 是否布置作业 */}
-          {props.item.isNotWork && <i class={styles.iconNoWork}></i>}
-          {/* 是否有添加逻辑 */}
-          {props.isShowAdd && (
-            <div class={styles.function}>
-              <NTooltip showArrow={false} duration={30} animated={false}>
-                {{
-                  trigger: () => (
-                    <i class={styles.iconLook} onClick={() => emit('look')}></i>
-                  ),
-                  default: () => '预览课件'
-                }}
-              </NTooltip>
-              <NTooltip showArrow={false} duration={30} animated={false}>
-                {{
-                  trigger: () => (
-                    <i class={styles.iconAdd} onClick={() => emit('add')}></i>
-                  ),
-                  default: () => '添加到我的课件'
-                }}
-              </NTooltip>
-            </div>
-          )}
-        </div>
-        <div class={styles.operationBottom}>
-          <div class={styles.coursewareText}>
-            <div class={[styles.name]}>
-              <span>{props.item.name}</span>
-              {/* , props.isEditName && styles.editName <i
-                class={styles.iconEditName}
-                onClick={() => emit('editName')}></i> */}
-            </div>
-            <div class={styles.subjectName}>{props.item.instrumentNames}</div>
-          </div>
-
-          {props.operate && (
-            <div class={styles.footer}>
-              <div
-                class={styles.actionClass}
-                onClick={() => emit('startClass')}>
-                开始上课
-              </div>
-
-              <NSpace>
-                <div
-                  class={[styles.actionClass, styles.actionWork]}
-                  onClick={() => emit('work')}>
-                  作业
-                </div>
-                <NPopover
-                  trigger="hover"
-                  showArrow={false}
-                  to={false}
-                  duration={50}>
-                  {{
-                    trigger: () => <div class={[styles.menu]}></div>,
-                    default: () => (
-                      <div class={styles.popoverList}>
-                        <div
-                          class={styles.popoverItem}
-                          onClick={() => emit('edit')}>
-                          <i class={styles.iconEdit}></i>
-                          <span>编辑课件</span>
-                        </div>
-                        <div
-                          class={styles.popoverItem}
-                          onClick={() => emit('delete')}>
-                          <i class={styles.iconDelete}></i>
-                          <span>删除课件</span>
-                        </div>
-                      </div>
-                    )
-                  }}
-                </NPopover>
-              </NSpace>
-            </div>
-          )}
-        </div>
-      </div>
-    );
-  }
-});
+import { defineComponent } from 'vue';
+import styles from './index.module.less';
+import { NButton, NImage, NPopover, NSpace, NTooltip } from 'naive-ui';
+// import iconEdit from '../../images/icon-courseware-edit.png';
+// import iconDelete from '../../images/icon-courseware-delete.png';
+// import iconEditName from '../../images/icon-edit-name.png';
+
+export default defineComponent({
+  name: 'courseware-type',
+  props: {
+    item: {
+      type: Object,
+      default: () => ({})
+    },
+    /** 是否鼠标滑动时显示显示添加按钮 */
+    isHoverShowAdd: {
+      type: Boolean,
+      default: true
+    },
+    /** 是否显示添加按钮 */
+    isShowAdd: {
+      type: Boolean,
+      default: false
+    },
+    /** 是否支持编辑名称 */
+    isEditName: {
+      type: Boolean,
+      default: false
+    },
+    /** 是否显示操作按钮 */
+    operate: {
+      type: Boolean,
+      default: false
+    },
+    /** 是否显示预览按钮 */
+    isShowPreviewBtn: {
+      type: Boolean,
+      default: false
+    },
+    isShowOpenFlag: {
+      type: Boolean,
+      default: true
+    }
+  },
+  /** add */
+  emits: [
+    'add',
+    'editName',
+    'edit',
+    'delete',
+    'startClass',
+    'click',
+    'work',
+    'look'
+  ],
+  setup(props, { emit }) {
+    return () => (
+      <div
+        class={[
+          styles.coursewareType,
+          props.isHoverShowAdd
+            ? styles.coursewareTypeHover
+            : styles.coursewareTypeHocoursewareTypeShow
+        ]}>
+        <div
+          class={[
+            styles.cover,
+            props.isShowPreviewBtn && styles.hideP,
+            props.isShowAdd && styles.isShowAdd
+          ]}
+          onClick={() => emit('click')}>
+          {props.item.openFlag && props.isShowOpenFlag && (
+            <span class={styles.status}>公开</span>
+          )}
+          <NImage
+            objectFit="cover"
+            previewDisabled
+            src={props.item.coverImg}
+            class={!props.item.coverImg && styles.noCoverImg}
+          />
+
+          <i class={styles.defaultLook}></i>
+
+          {props.isShowPreviewBtn && (
+            <div class={styles.preview}>
+              <NButton strong secondary class={styles.previewBtn}>
+                使用课件
+              </NButton>
+            </div>
+          )}
+
+          {/* 是否布置作业 */}
+          {props.item.isNotWork && <i class={styles.iconNoWork}></i>}
+          {/* 是否有添加逻辑 */}
+          {props.isShowAdd && (
+            <div class={styles.function}>
+              <NTooltip showArrow={false} duration={30} animated={false}>
+                {{
+                  trigger: () => (
+                    <i class={styles.iconLook} onClick={() => emit('look')}></i>
+                  ),
+                  default: () => '预览课件'
+                }}
+              </NTooltip>
+              <NTooltip showArrow={false} duration={30} animated={false}>
+                {{
+                  trigger: () => (
+                    <i class={styles.iconAdd} onClick={() => emit('add')}></i>
+                  ),
+                  default: () => '添加到我的课件'
+                }}
+              </NTooltip>
+            </div>
+          )}
+        </div>
+        <div class={styles.operationBottom}>
+          <div class={styles.coursewareText}>
+            <div class={[styles.name]}>
+              <span>{props.item.name}</span>
+              {/* , props.isEditName && styles.editName <i
+                class={styles.iconEditName}
+                onClick={() => emit('editName')}></i> */}
+            </div>
+            <div class={styles.subjectName}>{props.item.instrumentNames}</div>
+          </div>
+
+          {props.operate && (
+            <div class={styles.footer}>
+              <div
+                class={styles.actionClass}
+                onClick={() => emit('startClass')}>
+                开始上课
+              </div>
+
+              <NSpace>
+                <div
+                  class={[styles.actionClass, styles.actionWork]}
+                  onClick={() => emit('work')}>
+                  作业
+                </div>
+                <NPopover
+                  trigger="hover"
+                  showArrow={false}
+                  to={false}
+                  duration={50}>
+                  {{
+                    trigger: () => <div class={[styles.menu]}></div>,
+                    default: () => (
+                      <div class={styles.popoverList}>
+                        <div
+                          class={styles.popoverItem}
+                          onClick={() => emit('edit')}>
+                          <i class={styles.iconEdit}></i>
+                          <span>编辑课件</span>
+                        </div>
+                        <div
+                          class={styles.popoverItem}
+                          onClick={() => emit('delete')}>
+                          <i class={styles.iconDelete}></i>
+                          <span>删除课件</span>
+                        </div>
+                      </div>
+                    )
+                  }}
+                </NPopover>
+              </NSpace>
+            </div>
+          )}
+        </div>
+      </div>
+    );
+  }
+});

+ 62 - 53
src/views/setting/api.ts

@@ -1,53 +1,62 @@
-import request from '@/utils/request';
-
-/**
- * 老师列表
- */
-export const api_teacherPage = (params: any) => {
-  return request.post('/edu-app/teacher/page', {
-    data: params
-  });
-};
-
-/**
- * 老师新增
- */
-export const api_teacherAdd = (params: object) => {
-  return request.post('/edu-app/teacher/add', {
-    data: params
-  });
-};
-/**
- * 老师停用/启用
- */
-export const api_tenantInfoUpdateStatus = (params: object) => {
-  return request.post('/edu-app/teacher/updateStatus', {
-    data: params
-  });
-};
-/**
- * 老师重置密码
- */
-export const api_userResetPassword = (params: object) => {
-  return request.post('/edu-app/user/resetPassword', {
-    data: params,
-    requestType: 'form'
-  });
-};
-
-/** 分页查询机构 */
-export const api_tenantInfoPage = (params: object) => {
-  return request.post('/edu-app/tenantInfo/page', {
-    data: params
-  });
-};
-/** 更新学校信息 */
-export const api_schoolUpdate = (params: object) => {
-  return request.post('/edu-app/school/update', {
-    data: params
-  });
-};
-/** 获取省市区 */
-export const api_sysAreaQueryAllProvince = () => {
-  return request.get('/edu-app/open/sysArea/queryAllProvince');
-};
+import request from '@/utils/request';
+
+/**
+ * 老师列表
+ */
+export const api_teacherPage = (params: any) => {
+  return request.post('/edu-app/teacher/page', {
+    data: params
+  });
+};
+
+/**
+ * 老师新增
+ */
+export const api_teacherAdd = (params: object) => {
+  return request.post('/edu-app/teacher/add', {
+    data: params
+  });
+};
+/**
+ * 老师停用/启用
+ */
+export const api_tenantInfoUpdateStatus = (params: object) => {
+  return request.post('/edu-app/teacher/updateStatus', {
+    data: params
+  });
+};
+/**
+ * 老师重置密码
+ */
+export const api_userResetPassword = (params: object) => {
+  return request.post('/edu-app/user/resetPassword', {
+    data: params,
+    requestType: 'form'
+  });
+};
+
+/** 分页查询机构 */
+export const api_tenantInfoPage = (params: object) => {
+  return request.post('/edu-app/tenantInfo/page', {
+    data: params
+  });
+};
+/** 更新学校信息 */
+export const api_schoolUpdate = (params: object) => {
+  return request.post('/edu-app/school/update', {
+    data: params
+  });
+};
+/** 获取省市区 */
+export const api_sysAreaQueryAllProvince = () => {
+  return request.get('/edu-app/open/sysArea/queryAllProvince');
+};
+
+/**
+ * 老师管理 - 更换负责人
+ */
+export const updateAdmin = (params?: any) => {
+  return request.post('/edu-app/teacher/updateAdmin', {
+    data: params
+  });
+};

+ 490 - 467
src/views/setting/components/schoolInfo/index.module.less

@@ -1,468 +1,491 @@
-.logo {
-  position: relative;
-  width: 100px;
-  height: 100px;
-  border-radius: 50%;
-  overflow: hidden;
-
-  :global {
-    .n-image {
-      width: 100%;
-      height: 100%;
-    }
-  }
-
-  .changeHead {
-    position: absolute;
-    left: 0;
-    right: 0;
-    top: 0;
-    bottom: 0;
-    background-color: rgba(0, 0, 0, .7);
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    font-size: 16px;
-    color: #fff;
-    font-weight: 600;
-    transition: opacity .3s;
-    border-radius: 50%;
-    cursor: pointer;
-    opacity: 0;
-
-    &:hover {
-      opacity: 1;
-    }
-  }
-
-  .uploadFile {
-    position: absolute;
-    left: 0;
-    right: 0;
-    top: 0;
-    bottom: 0;
-    opacity: 0;
-  }
-}
-
-.formWrap {
-  :global {
-    .n-input {
-      width: 284px;
-      border-radius: 8px;
-
-      .n-input__input-el {
-        height: 50px;
-        font-size: 16px;
-      }
-
-      &.n-input--disabled {
-        background-color: #F5F6FA;
-        .n-input__input-el {
-          color: rgba(0, 0, 0, 0.4);
-        }
-      }
-    }
-
-
-    .n-base-selection {
-      height: 50px;
-      width: 284px;
-      border-radius: 8px;
-
-      .n-base-selection-label {
-        height: 50px;
-        font-size: 16px;
-      }
-    }
-
-    .n-base-selection.n-base-selection--disabled .n-base-selection-label {
-      background-color: #F5F6FA;
-      color: rgba(0, 0, 0, 0.4);
-    }
-
-    .n-base-selection.n-base-selection--disabled .n-base-selection-label .n-base-selection-input {
-      color: rgba(0, 0, 0, 0.4) !important;
-    }
-  }
-}
-
-.schoolInfo {
-  :global {
-    .n-form-item .n-form-item-label {
-      color: #777;
-    }
-
-    .n-button {
-      border-radius: 8px;
-    }
-
-    .n-data-table .n-data-table-th {
-
-      background: #F7F7F8;
-      color: rgba(113, 113, 114, 1) !important;
-      border: none;
-      min-height: 54px;
-      font-size: 15px;
-    }
-
-    .n-data-table.n-data-table--bordered .n-data-table-wrapper {
-      border: none;
-    }
-
-    .n-data-table-tr .n-data-table-td .n-button__content,
-    .n-data-table .n-data-table-td {
-      font-weight: bold;
-      font-size: 15px;
-    }
-  }
-
-  .errorBtn {
-    :global {
-      .n-button__content {
-        color: #FF4D4F;
-      }
-    }
-  }
-}
-
-.addTeacher {
-  padding: 0;
-  border-radius: 16px;
-  overflow: hidden;
-  min-width: 456px;
-
-  :global {
-    .n-dialog__close {
-      transform: translate(0, 3px);
-    }
-
-    .n-dialog__title {
-      min-height: 70px;
-      justify-content: center;
-      background: #F5F6FA;
-    }
-
-    .n-form {
-      padding: 20px 0;
-    }
-
-    .n-input {
-      border-radius: 8px;
-
-      .n-input__input-el {
-        height: 50px;
-        font-size: 16px;
-      }
-
-      &.n-input--disabled {
-        background-color: #F5F6FA;
-        color: rgba(149, 149, 152, 1);
-      }
-    }
-
-    .n-base-selection {
-      border-radius: 8px;
-
-      .n-base-selection-label {
-        height: 50px;
-        font-size: 16px;
-      }
-    }
-
-    .n-base-selection.n-base-selection--disabled .n-base-selection-label {
-      background-color: #F5F6FA;
-      color: rgba(149, 149, 152, 1);
-    }
-
-    .n-form-item-blank {
-      padding-right: 30px;
-    }
-
-    .genderBtn {
-      min-width: 84px;
-      min-height: 37px;
-      border-radius: 8px;
-    }
-
-    .n-form-item-label {
-      color: #777;
-      padding: 0;
-      font-size: 18px;
-    }
-
-    .n-form-item-label__text {
-      height: 50px;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-    }
-
-    .nalert {
-      padding: 0 30px;
-
-      .n-alert {
-        background: #FFE8E8;
-        text-align: center;
-      }
-
-      .n-alert-body .n-alert-body__content {
-        color: #EA4132;
-        font-size: 14px;
-      }
-
-    }
-
-    .actionBtn {
-      width: 156px;
-      height: 47px;
-      font-size: 18px;
-    }
-  }
-}
-
-.btnList {
-  width: 100%;
-
-  .btn {
-    width: 144px;
-    height: 45px;
-    border-radius: 8px;
-    font-size: 18px;
-    font-weight: 600 !important;
-    margin-right: 24px;
-  }
-
-}
-
-
-
-
-
-.addStudentWrap {
-  position: relative;
-  width: 378px;
-  height: 631px;
-  margin: 120px auto 0;
-
-  .studentCLose {
-    cursor: pointer;
-    position: absolute;
-    right: -67px;
-    top: -54px;
-    width: 42px;
-    height: 42px;
-    z-index: 100;
-  }
-
-  .stunentStart {
-    position: absolute;
-    width: 556px;
-    height: 246px;
-    left: -70px;
-    top: -98px;
-
-    img {
-      width: 556px;
-      height: 246px;
-    }
-  }
-
-  .addTitle {
-    width: 212px;
-    height: 40px;
-    top: -9px;
-    position: absolute;
-    margin: 0 auto;
-    left: 50%;
-    margin-left: -106px;
-    z-index: 100;
-
-    img {
-      width: 212px;
-      height: 40px;
-    }
-
-    &.addTeacherTitle {
-      top: -12px;
-      height: 40px;
-
-      img {
-        height: 40px
-      }
-    }
-  }
-
-  .addStudentInfo {
-    width: 378px;
-    height: 631px;
-    position: relative;
-
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-
-    .studentInfoBg {
-      position: absolute;
-      width: 378px;
-      height: 631px;
-
-      img {
-        left: 0;
-        top: 0;
-        width: 378px;
-        height: 631px;
-      }
-    }
-
-
-
-    .studentCore {
-      position: absolute;
-      bottom: 27px;
-      left: 24px;
-      width: 330px;
-      height: 339px;
-      background: rgba(255, 255, 255, 0.33);
-      border-radius: 17px;
-      border: 2px solid #ffffff;
-      backdrop-filter: blur(17px);
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-
-      .schoolLogo {
-        width: 67px;
-        height: 67px;
-        margin-top: -34px;
-        border: 1px solid #fff;
-        border-radius: 50%;
-        z-index: 100;
-        overflow: hidden;
-        background-color: #fff;
-        position: absolute;
-      }
-
-      .studentCoreInfo {
-        margin-top: 6px;
-        width: 314px;
-        height: 323px;
-        background: #ffffff;
-        border-radius: 14px;
-
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-
-        h2 {
-          margin-top: 37px;
-          height: 22px;
-          font-size: 16px;
-          font-weight: 600;
-          color: #000000;
-          line-height: 22px;
-          margin-bottom: 6px;
-          overflow: hidden;
-          text-overflow: ellipsis;
-          white-space: nowrap;
-        }
-
-        .studentCoreInfoSubtitle {
-          font-size: 14px;
-          font-weight: 400;
-          color: #000000;
-
-          span {
-            color: #198cfe;
-            font-weight: 600;
-          }
-        }
-
-        .codewrap {
-          width: 147px;
-          height: 145px;
-          // background: url(./images/cordWrap.png) no-repeat;
-          position: relative;
-          // background-size: 147px 145px;
-          margin: 16px 0 18px;
-          display: flex;
-          flex-direction: column;
-          align-items: center;
-          justify-content: center;
-
-          .codewrapBg {
-            width: 147px !important;
-            height: 145px !important;
-            top: 0;
-            left: 0;
-            position: absolute;
-          }
-
-          // img {
-
-          // }
-
-
-        }
-
-
-        .codewrapSubmit {
-          width: 213px;
-          height: 35px;
-          // background: linear-gradient(135deg, #d1fdf9 0%, #d6eeff 100%);
-          // box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, 0.62);
-          border-radius: 18px;
-          text-align: center;
-          line-height: 35px;
-          font-size: 14px;
-          color: #117de9;
-          position: relative;
-
-          img {
-            position: absolute;
-            left: 0;
-            top: 0;
-            width: 213px;
-            height: 35px;
-          }
-
-          span {
-            font-weight: 600;
-          }
-        }
-      }
-    }
-  }
-
-  .studentBottom {
-    width: 420px;
-
-    position: absolute;
-    left: -21px;
-    bottom: -120px;
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-
-    p {
-      text-align: center;
-      font-size: 16px;
-      color: #ffffff;
-      margin-bottom: 30px;
-    }
-
-    .downBtn {
-      width: 256px;
-      height: 54px;
-      background: linear-gradient(291deg, #02BAFF 0%, #007AFE 100%);
-      border-radius: 30px;
-      line-height: 54px;
-      font-size: 22px;
-      font-weight: 600;
-      text-align: center;
-      color: #fff;
-
-      cursor: pointer;
-    }
-  }
+.logo {
+  position: relative;
+  width: 100px;
+  height: 100px;
+  border-radius: 50%;
+  overflow: hidden;
+
+  :global {
+    .n-image {
+      width: 100%;
+      height: 100%;
+    }
+  }
+
+  .changeHead {
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, .7);
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 16px;
+    color: #fff;
+    font-weight: 600;
+    transition: opacity .3s;
+    border-radius: 50%;
+    cursor: pointer;
+    opacity: 0;
+
+    &:hover {
+      opacity: 1;
+    }
+  }
+
+  .uploadFile {
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    opacity: 0;
+  }
+}
+
+.formWrap {
+  :global {
+    .n-input {
+      width: 284px;
+      border-radius: 8px;
+
+      .n-input__input-el {
+        height: 50px;
+        font-size: 16px;
+      }
+
+      &.n-input--disabled {
+        background-color: #F5F6FA;
+
+        .n-input__input-el {
+          color: rgba(0, 0, 0, 0.4);
+        }
+      }
+    }
+
+
+    .n-base-selection {
+      height: 50px;
+      width: 284px;
+      border-radius: 8px;
+
+      .n-base-selection-label {
+        height: 50px;
+        font-size: 16px;
+      }
+    }
+
+    .n-base-selection.n-base-selection--disabled .n-base-selection-label {
+      background-color: #F5F6FA;
+      color: rgba(0, 0, 0, 0.4);
+    }
+
+    .n-base-selection.n-base-selection--disabled .n-base-selection-label .n-base-selection-input {
+      color: rgba(0, 0, 0, 0.4) !important;
+    }
+  }
+}
+
+.schoolInfo {
+  :global {
+    .n-form-item .n-form-item-label {
+      color: #777;
+    }
+
+    .n-button {
+      border-radius: 8px;
+    }
+
+    // .n-data-table .n-data-table-th {
+
+    //   background: #F7F7F8;
+    //   color: rgba(113, 113, 114, 1) !important;
+    //   border: none;
+    //   min-height: 54px;
+    //   font-size: 15px;
+    // }
+
+    // .n-data-table.n-data-table--bordered .n-data-table-wrapper {
+    //   border: none;
+    // }
+
+    // .n-data-table-tr .n-data-table-td .n-button__content,
+    // .n-data-table .n-data-table-td {
+    //   font-weight: bold;
+    //   font-size: 15px;
+    // }
+  }
+
+  .errorBtn {
+    :global {
+      .n-button__content {
+        color: #FF4D4F;
+      }
+    }
+  }
+
+}
+
+.removeVisiable1 {
+  width: 432px;
+
+  // :global {
+  //   .n-card-header {
+  //     font-size: max(22px, 16Px);
+  //   }
+  // }
+
+  .btnGroupModal {
+    padding: 32px 0;
+
+    :global {
+      .n-button {
+        height: 47px;
+        min-width: 156px;
+      }
+    }
+  }
+}
+
+.addTeacher {
+  padding: 0;
+  border-radius: 16px;
+  overflow: hidden;
+  min-width: 456px;
+
+  :global {
+    .n-dialog__close {
+      transform: translate(0, 3px);
+    }
+
+    .n-dialog__title {
+      min-height: 70px;
+      justify-content: center;
+      background: #F5F6FA;
+    }
+
+    .n-form {
+      padding: 20px 0;
+    }
+
+    .n-input {
+      border-radius: 8px;
+
+      .n-input__input-el {
+        height: 50px;
+        font-size: 16px;
+      }
+
+      &.n-input--disabled {
+        background-color: #F5F6FA;
+        color: rgba(149, 149, 152, 1);
+      }
+    }
+
+    .n-base-selection {
+      border-radius: 8px;
+
+      .n-base-selection-label {
+        height: 50px;
+        font-size: 16px;
+      }
+    }
+
+    .n-base-selection.n-base-selection--disabled .n-base-selection-label {
+      background-color: #F5F6FA;
+      color: rgba(149, 149, 152, 1);
+    }
+
+    .n-form-item-blank {
+      padding-right: 30px;
+    }
+
+    .genderBtn {
+      min-width: 84px;
+      min-height: 37px;
+      border-radius: 8px;
+    }
+
+    .n-form-item-label {
+      color: #777;
+      padding: 0;
+      font-size: 18px;
+    }
+
+    .n-form-item-label__text {
+      height: 50px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+
+    .nalert {
+      padding: 0 30px;
+
+      .n-alert {
+        background: #FFE8E8;
+        text-align: center;
+      }
+
+      .n-alert-body .n-alert-body__content {
+        color: #EA4132;
+        font-size: 14px;
+      }
+
+    }
+
+    .actionBtn {
+      width: 156px;
+      height: 47px;
+      font-size: 18px;
+    }
+  }
+}
+
+.btnList {
+  width: 100%;
+
+  .btn {
+    width: 144px;
+    height: 45px;
+    border-radius: 8px;
+    font-size: 18px;
+    font-weight: 600 !important;
+    margin-right: 24px;
+  }
+
+}
+
+
+
+
+
+.addStudentWrap {
+  position: relative;
+  width: 378px;
+  height: 631px;
+  margin: 120px auto 0;
+
+  .studentCLose {
+    cursor: pointer;
+    position: absolute;
+    right: -67px;
+    top: -54px;
+    width: 42px;
+    height: 42px;
+    z-index: 100;
+  }
+
+  .stunentStart {
+    position: absolute;
+    width: 556px;
+    height: 246px;
+    left: -70px;
+    top: -98px;
+
+    img {
+      width: 556px;
+      height: 246px;
+    }
+  }
+
+  .addTitle {
+    width: 212px;
+    height: 40px;
+    top: -9px;
+    position: absolute;
+    margin: 0 auto;
+    left: 50%;
+    margin-left: -106px;
+    z-index: 100;
+
+    img {
+      width: 212px;
+      height: 40px;
+    }
+
+    &.addTeacherTitle {
+      top: -12px;
+      height: 40px;
+
+      img {
+        height: 40px
+      }
+    }
+  }
+
+  .addStudentInfo {
+    width: 378px;
+    height: 631px;
+    position: relative;
+
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+
+    .studentInfoBg {
+      position: absolute;
+      width: 378px;
+      height: 631px;
+
+      img {
+        left: 0;
+        top: 0;
+        width: 378px;
+        height: 631px;
+      }
+    }
+
+
+
+    .studentCore {
+      position: absolute;
+      bottom: 27px;
+      left: 24px;
+      width: 330px;
+      height: 339px;
+      background: rgba(255, 255, 255, 0.33);
+      border-radius: 17px;
+      border: 2px solid #ffffff;
+      backdrop-filter: blur(17px);
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+
+      .schoolLogo {
+        width: 67px;
+        height: 67px;
+        margin-top: -34px;
+        border: 1px solid #fff;
+        border-radius: 50%;
+        z-index: 100;
+        overflow: hidden;
+        background-color: #fff;
+        position: absolute;
+      }
+
+      .studentCoreInfo {
+        margin-top: 6px;
+        width: 314px;
+        height: 323px;
+        background: #ffffff;
+        border-radius: 14px;
+
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+
+        h2 {
+          margin-top: 37px;
+          height: 22px;
+          font-size: 16px;
+          font-weight: 600;
+          color: #000000;
+          line-height: 22px;
+          margin-bottom: 6px;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+        }
+
+        .studentCoreInfoSubtitle {
+          font-size: 14px;
+          font-weight: 400;
+          color: #000000;
+
+          span {
+            color: #198cfe;
+            font-weight: 600;
+          }
+        }
+
+        .codewrap {
+          width: 147px;
+          height: 145px;
+          // background: url(./images/cordWrap.png) no-repeat;
+          position: relative;
+          // background-size: 147px 145px;
+          margin: 16px 0 18px;
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          justify-content: center;
+
+          .codewrapBg {
+            width: 147px !important;
+            height: 145px !important;
+            top: 0;
+            left: 0;
+            position: absolute;
+          }
+
+          // img {
+
+          // }
+
+
+        }
+
+
+        .codewrapSubmit {
+          width: 213px;
+          height: 35px;
+          // background: linear-gradient(135deg, #d1fdf9 0%, #d6eeff 100%);
+          // box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, 0.62);
+          border-radius: 18px;
+          text-align: center;
+          line-height: 35px;
+          font-size: 14px;
+          color: #117de9;
+          position: relative;
+
+          img {
+            position: absolute;
+            left: 0;
+            top: 0;
+            width: 213px;
+            height: 35px;
+          }
+
+          span {
+            font-weight: 600;
+          }
+        }
+      }
+    }
+  }
+
+  .studentBottom {
+    width: 420px;
+
+    position: absolute;
+    left: -21px;
+    bottom: -120px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+
+    p {
+      text-align: center;
+      font-size: 16px;
+      color: #ffffff;
+      margin-bottom: 30px;
+    }
+
+    .downBtn {
+      width: 256px;
+      height: 54px;
+      background: linear-gradient(291deg, #02BAFF 0%, #007AFE 100%);
+      border-radius: 30px;
+      line-height: 54px;
+      font-size: 22px;
+      font-weight: 600;
+      text-align: center;
+      color: #fff;
+
+      cursor: pointer;
+    }
+  }
 }

+ 455 - 398
src/views/setting/components/schoolInfo/index.tsx

@@ -1,398 +1,455 @@
-import {
-  DataTableColumn,
-  NButton,
-  NCascader,
-  NDataTable,
-  NForm,
-  NFormItem,
-  NIcon,
-  NImage,
-  NInput,
-  NModal,
-  NSpace,
-  useDialog,
-  useMessage
-} from 'naive-ui';
-import { defineComponent, nextTick, onMounted, reactive, ref } from 'vue';
-import styles from './index.module.less';
-import { useUserStore } from '/src/store/modules/users';
-import UploadFile from '/src/components/upload-file';
-import { Add } from '@vicons/ionicons5';
-import {
-  api_schoolUpdate,
-  api_sysAreaQueryAllProvince,
-  api_teacherPage,
-  api_tenantInfoUpdateStatus,
-  api_userResetPassword
-} from '../../api';
-import AddTeacher from '../../modal/add-teacher';
-import TheQrCode from '/src/components/TheQrCode';
-import logo from '@/common/images/logo.png';
-import { stringifyQuery } from '/src/router';
-import AddteacherModel from '../../modal/addteacherModel';
-import TeacherGuide from '@/custom-plugins/guide-page/teacher-guide';
-import TheEmpty from '/src/components/TheEmpty';
-export default defineComponent({
-  name: 'school-info',
-  setup() {
-    const user = useUserStore();
-    const formOptions = reactive({
-      areaList: [] as any[]
-    });
-    const forms = reactive({
-      name: user.info.schoolInfos?.[0]?.name,
-      logo: user.info.schoolInfos?.[0]?.logo || user.info.avatar,
-      provinceCode: user.info.schoolInfos?.[0]?.provinceCode || '', // 省份编码
-      cityCode: user.info.schoolInfos?.[0]?.cityCode || '', // 城市编码
-      regionCode: user.info.schoolInfos?.[0]?.regionCode || '' // 区域编码
-    });
-    const data = reactive({
-      loading: false,
-      schoolLoading: true,
-      dataList: [] as any[],
-      disabled: true,
-
-      modal: false,
-      qrModal: false,
-      oldTecherform: {} as any,
-      oldLoading: false
-    });
-    const showGuide = ref(false);
-    const columns = (): DataTableColumn[] => {
-      return [
-        {
-          title: '老师姓名',
-          key: 'nickname',
-          render: (row: any) => {
-            return (
-              <div
-                style={{ userSelect: 'all', cursor: 'pointer' }}
-                onClick={() => copyTo(row.nickname)}>
-                {row.nickname}
-              </div>
-            );
-          }
-        },
-        {
-          title: '手机号码',
-          key: 'phone',
-          render: (row: any) => {
-            return (
-              <div
-                style={{ userSelect: 'all', cursor: 'pointer' }}
-                onClick={() => copyTo(row.phone)}>
-                {row.phone}
-              </div>
-            );
-          }
-        },
-        {
-          title: '性别',
-          key: 'questionTypeCode',
-          render: (row: any) => {
-            return <div>{row.gender ? '男' : '女'}</div>;
-          }
-        },
-        {
-          title: '状态',
-          key: 'statusName',
-          render: (row: any) => {
-            return (
-              <div>
-                {row.status === 'ACTIVATION' ? (
-                  <NButton text>启用</NButton>
-                ) : (
-                  <NButton class={styles.errorBtn} text>
-                    冻结
-                  </NButton>
-                )}
-              </div>
-            );
-          }
-        },
-        {
-          title: '操作',
-          key: 'titleImg',
-          render: (row: any) => (
-            <NSpace>
-              <NButton type="primary" text onClick={() => onResetPassword(row)}>
-                重置密码
-              </NButton>
-
-              {row.status === 'ACTIVATION' ? (
-                <NButton
-                  disabled={row.jobType === 'ADMIN'}
-                  type="primary"
-                  text
-                  onClick={() => handleChange(row)}>
-                  冻结
-                </NButton>
-              ) : (
-                <NButton
-                  class={styles.errorBtn}
-                  text
-                  onClick={() => handleChange(row)}>
-                  解冻
-                </NButton>
-              )}
-            </NSpace>
-          )
-        }
-      ];
-    };
-    const getAreaList = async () => {
-      const res = await api_sysAreaQueryAllProvince();
-      if (res?.code === 200) {
-        formOptions.areaList = res.data;
-      }
-    };
-
-    const getList = async () => {
-      data.loading = true;
-      const res = await api_teacherPage({
-        schoolId: user.info.schoolInfos?.[0]?.id,
-        // jobType: 'TEACHER',
-        // jobType: 'ADMIN',
-        page: 1,
-        rows: 1000
-      });
-      data.loading = false;
-      if (res?.code === 200 && Array.isArray(res?.data?.rows)) {
-        data.dataList = res.data.rows;
-      }
-      setTimeout(() => {
-        showGuide.value = true;
-      }, 500);
-    };
-    onMounted(() => {
-      getAreaList();
-      getList();
-    });
-
-    const dialog = useDialog();
-    const message = useMessage();
-    const handleChange = (row: any) => {
-      const statuStr = row.status === 'LOCKED' ? '解冻' : '冻结';
-      dialog.warning({
-        title: '温馨提示',
-        content: `是否${statuStr}"${row.nickname}"?`,
-        positiveText: '确定',
-        negativeText: '取消',
-        onPositiveClick: async () => {
-          await api_tenantInfoUpdateStatus({
-            ids: [row.id],
-            status: row.status === 'LOCKED' ? 'ACTIVATION' : 'LOCKED'
-          });
-          getList();
-          message.success(statuStr + '成功');
-        }
-      });
-    };
-    // 重置密码
-    const onResetPassword = (row: any): void => {
-      dialog.warning({
-        title: '警告',
-        content: `重置"${row.nickname}"的密码,是否继续?`,
-        positiveText: '确定',
-        negativeText: '取消',
-        onPositiveClick: async () => {
-          await api_userResetPassword({
-            userId: row.id,
-            clientType: 'TEACHER'
-          });
-          message.success('重置成功');
-        }
-      });
-    };
-    const formRef = ref();
-    const changeSchoolInfo = () => {
-      formRef.value?.validate(async (err: any) => {
-        if (err) {
-          return;
-        }
-        data.schoolLoading = false;
-        await api_schoolUpdate({ ...user.info.schoolInfos?.[0], ...forms });
-        data.schoolLoading = true;
-        message.success('修改成功');
-        data.disabled = true;
-      });
-    };
-
-    const registerUrl = () => {
-      const queryStr = `tenantId=${user.info.schoolInfos?.[0]?.tenantId}&schoolId=${user.info.schoolInfos?.[0]?.id}&schoolName=${user.info.schoolInfos?.[0]?.name}`;
-      const url =
-        `${location.origin}/classroom-app/#/teaher-register?` + queryStr;
-      console.log(url);
-      return url;
-    };
-
-    const copyTo = (text: string) => {
-      const input = document.createElement('input');
-      input.value = text;
-      document.body.appendChild(input);
-      input.select();
-      input.setSelectionRange(0, input.value.length);
-      document.execCommand('Copy');
-      document.body.removeChild(input);
-      message.success('复制成功');
-    };
-    return () => (
-      <div class={styles.schoolInfo}>
-        <NForm
-          ref={formRef}
-          class={styles.formWrap}
-          model={forms}
-          style={{ padding: '30px 0' }}
-          disabled={data.disabled}>
-          <NSpace size={[30, 20]}>
-            <div class={styles.logo}>
-              <NImage
-                previewDisabled={false}
-                src={forms.logo}
-                objectFit="contain"
-              />
-              <div
-                style={{ display: data.disabled ? 'none' : '' }}
-                class={styles.changeHead}>
-                修改头像
-                {data.schoolLoading && (
-                  <UploadFile
-                    class={[styles.uploadFile]}
-                    cropper
-                    onUpdate:fileList={val => {
-                      forms.logo = val;
-                    }}
-                  />
-                )}
-              </div>
-            </div>
-            <NFormItem
-              label="学校名称"
-              path="name"
-              showRequireMark={false}
-              rule={[
-                { required: true, message: '请填写学校名称', trigger: 'blur' }
-              ]}>
-              <NInput
-                bordered={!data.disabled}
-                maxlength={20}
-                v-model:value={forms.name}
-              />
-            </NFormItem>
-            <NFormItem label="城区">
-              {!data.oldLoading && <NCascader
-                placeholder="请选择城区"
-                bordered={!data.disabled}
-                options={formOptions.areaList}
-                labelField="name"
-                valueField="code"
-                childrenField="areas"
-                checkStrategy="child"
-                expandTrigger="hover"
-                defaultValue={
-                  user.info.schoolInfos?.[0]?.regionCode ||
-                  user.info.schoolInfos?.[0]?.cityCode ||
-                  user.info.schoolInfos?.[0]?.provinceCode
-                }
-                onUpdate:value={(val: any, option: any, pathValues: any) => {
-                  forms.provinceCode = pathValues[0]?.code;
-                  forms.cityCode = pathValues[1]?.code;
-                  forms.regionCode = pathValues[2]?.code;
-                }}
-              />}
-            </NFormItem>
-            <NFormItem>
-              {data.disabled ? (
-                <NSpace class={styles.btnList} align="center" justify="end">
-                  <NButton
-                    class={styles.btn}
-                    color="#f24433"
-                    onClick={() => {
-                      data.oldTecherform = Object.assign({}, forms);
-                      data.disabled = false;
-                    }}>
-                    修改信息
-                  </NButton>
-                </NSpace>
-              ) : (
-                <NSpace class={styles.btnList} align="center" justify="end">
-                  <NButton
-                    class={styles.btn}
-                    onClick={() => {
-                      Object.assign(forms, data.oldTecherform)
-                      data.disabled = true;
-                      data.oldLoading = true;
-                      nextTick(() => {
-                        data.oldLoading = false;
-                      })
-                    }}>
-                    取消
-                  </NButton>
-                  <NButton
-                    class={styles.btn}
-                    loading={!data.schoolLoading}
-                    type="primary"
-                    onClick={() => changeSchoolInfo()}>
-                    完成
-                  </NButton>
-                </NSpace>
-              )}
-            </NFormItem>
-          </NSpace>
-        </NForm>
-
-        <NSpace style={{ padding: '32px 0' }}>
-          <NButton
-              focusable={false}
-            {...{ id: 'teacher-0' }}
-            type="primary"
-            renderIcon={() => <NIcon component={<Add />} />}
-            onClick={() => (data.modal = true)}>
-            添加老师
-          </NButton>
-          <NButton
-            focusable={false}
-            {...{ id: 'teacher-1' }}
-            type="primary"
-            onClick={() => (data.qrModal = true)}>
-            老师注册二维码
-
-          </NButton>
-        </NSpace>
-
-        <NDataTable
-          v-slots={{
-            empty: () => <TheEmpty></TheEmpty>
-          }}
-          loading={data.loading}
-          columns={columns()}
-          data={data.dataList}></NDataTable>
-
-        <NModal
-          class={styles.addTeacher}
-          v-model:show={data.modal}
-          title="添加老师"
-          preset="dialog"
-          showIcon={false}>
-          <AddTeacher
-            areaList={formOptions.areaList}
-            onClose={() => {
-              data.modal = false;
-              getList();
-            }}
-          />
-        </NModal>
-
-        {data.qrModal ? (
-          <div v-model:show={data.qrModal} class="n-modal-mask">
-            <AddteacherModel
-              onClose={() => {
-                data.qrModal = false;
-              }}></AddteacherModel>
-          </div>
-        ) : null}
-        {showGuide.value ? <TeacherGuide></TeacherGuide> : null}
-      </div>
-    );
-  }
-});
+import {
+  DataTableColumn,
+  NButton,
+  NCascader,
+  NDataTable,
+  NForm,
+  NFormItem,
+  NIcon,
+  NImage,
+  NInput,
+  NModal,
+  NSpace,
+  useDialog,
+  useMessage
+} from 'naive-ui';
+import { defineComponent, nextTick, onMounted, reactive, ref } from 'vue';
+import styles from './index.module.less';
+import { useUserStore } from '/src/store/modules/users';
+import UploadFile from '/src/components/upload-file';
+import { Add } from '@vicons/ionicons5';
+import {
+  api_schoolUpdate,
+  api_sysAreaQueryAllProvince,
+  api_teacherPage,
+  api_tenantInfoUpdateStatus,
+  api_userResetPassword,
+  updateAdmin
+} from '../../api';
+import AddTeacher from '../../modal/add-teacher';
+import TheQrCode from '/src/components/TheQrCode';
+import logo from '@/common/images/logo.png';
+import { stringifyQuery } from '/src/router';
+import AddteacherModel from '../../modal/addteacherModel';
+import TeacherGuide from '@/custom-plugins/guide-page/teacher-guide';
+import TheEmpty from '/src/components/TheEmpty';
+import TheMessageDialog from '/src/components/TheMessageDialog';
+export default defineComponent({
+  name: 'school-info',
+  emits: ['changeTab'],
+  setup(props, { emit }) {
+    const user = useUserStore();
+    const formOptions = reactive({
+      areaList: [] as any[]
+    });
+    const forms = reactive({
+      name: user.info.schoolInfos?.[0]?.name,
+      schoolId: user.info.schoolInfos?.[0]?.id,
+      userId: user.info.id,
+      logo: user.info.schoolInfos?.[0]?.logo || user.info.avatar,
+      provinceCode: user.info.schoolInfos?.[0]?.provinceCode || '', // 省份编码
+      cityCode: user.info.schoolInfos?.[0]?.cityCode || '', // 城市编码
+      regionCode: user.info.schoolInfos?.[0]?.regionCode || '' // 区域编码
+    });
+    const data = reactive({
+      loading: false,
+      schoolLoading: true,
+      dataList: [] as any[],
+      disabled: true,
+      changeVisiable: false,
+      messageLoading: false,
+      activeRow: {} as any,
+
+      modal: false,
+      qrModal: false,
+      oldTecherform: {} as any,
+      oldLoading: false
+    });
+    const showGuide = ref(false);
+    const columns = (): DataTableColumn[] => {
+      return [
+        {
+          title: '老师姓名',
+          key: 'nickname',
+          render: (row: any) => {
+            return (
+              <div
+                style={{ userSelect: 'all', cursor: 'pointer' }}
+                onClick={() => copyTo(row.nickname)}>
+                {row.nickname}
+              </div>
+            );
+          }
+        },
+        {
+          title: '手机号码',
+          key: 'phone',
+          render: (row: any) => {
+            return (
+              <div
+                style={{ userSelect: 'all', cursor: 'pointer' }}
+                onClick={() => copyTo(row.phone)}>
+                {row.phone}
+              </div>
+            );
+          }
+        },
+        {
+          title: '性别',
+          key: 'questionTypeCode',
+          render: (row: any) => {
+            return <div>{row.gender ? '男' : '女'}</div>;
+          }
+        },
+        {
+          title: '状态',
+          key: 'statusName',
+          render: (row: any) => {
+            return (
+              <div>
+                {row.status === 'ACTIVATION' ? (
+                  <NButton text>启用</NButton>
+                ) : (
+                  <NButton class={styles.errorBtn} text>
+                    冻结
+                  </NButton>
+                )}
+              </div>
+            );
+          }
+        },
+        {
+          title: '操作',
+          key: 'titleImg',
+          render: (row: any) => (
+            <NSpace>
+              <NButton type="primary" text onClick={() => onResetPassword(row)}>
+                重置密码
+              </NButton>
+
+              {row.status === 'ACTIVATION' ? (
+                <>
+                  <NButton
+                    disabled={row.jobType === 'ADMIN'}
+                    type="primary"
+                    text
+                    onClick={() => handleChange(row)}>
+                    冻结
+                  </NButton>
+                  {row.jobType === 'TEACHER' && (
+                    <NButton
+                      type="primary"
+                      text
+                      onClick={() => {
+                        data.changeVisiable = true;
+                        data.activeRow = row;
+                      }}>
+                      转交管理
+                    </NButton>
+                  )}
+                </>
+              ) : (
+                <NButton
+                  class={styles.errorBtn}
+                  text
+                  onClick={() => handleChange(row)}>
+                  解冻
+                </NButton>
+              )}
+            </NSpace>
+          )
+        }
+      ];
+    };
+    const getAreaList = async () => {
+      const res = await api_sysAreaQueryAllProvince();
+      if (res?.code === 200) {
+        formOptions.areaList = res.data;
+      }
+    };
+
+    const getList = async () => {
+      data.loading = true;
+      const res = await api_teacherPage({
+        schoolId: user.info.schoolInfos?.[0]?.id,
+        // jobType: 'TEACHER',
+        // jobType: 'ADMIN',
+        page: 1,
+        rows: 1000
+      });
+      data.loading = false;
+      if (res?.code === 200 && Array.isArray(res?.data?.rows)) {
+        data.dataList = res.data.rows;
+      }
+      setTimeout(() => {
+        showGuide.value = true;
+      }, 500);
+    };
+
+    const onChangeManage = async () => {
+      console.log('111');
+
+      data.messageLoading = true;
+      try {
+        await updateAdmin({
+          school: forms.schoolId,
+          newAdminId: data.activeRow.id,
+          oldAdminId: forms.userId
+        });
+        message.success('转交成功');
+        emit('changeTab', 'person');
+        await user.getInfo();
+      } catch {
+        //
+      }
+      data.messageLoading = false;
+    };
+
+    onMounted(() => {
+      getAreaList();
+      getList();
+    });
+
+    const dialog = useDialog();
+    const message = useMessage();
+    const handleChange = (row: any) => {
+      const statuStr = row.status === 'LOCKED' ? '解冻' : '冻结';
+      dialog.warning({
+        title: '温馨提示',
+        content: `是否${statuStr}"${row.nickname}"?`,
+        positiveText: '确定',
+        negativeText: '取消',
+        onPositiveClick: async () => {
+          await api_tenantInfoUpdateStatus({
+            ids: [row.id],
+            status: row.status === 'LOCKED' ? 'ACTIVATION' : 'LOCKED'
+          });
+          getList();
+          message.success(statuStr + '成功');
+        }
+      });
+    };
+    // 重置密码
+    const onResetPassword = (row: any): void => {
+      dialog.warning({
+        title: '警告',
+        content: `重置"${row.nickname}"的密码,是否继续?`,
+        positiveText: '确定',
+        negativeText: '取消',
+        onPositiveClick: async () => {
+          await api_userResetPassword({
+            userId: row.id,
+            clientType: 'TEACHER'
+          });
+          message.success('重置成功');
+        }
+      });
+    };
+    const formRef = ref();
+    const changeSchoolInfo = () => {
+      formRef.value?.validate(async (err: any) => {
+        if (err) {
+          return;
+        }
+        data.schoolLoading = false;
+        await api_schoolUpdate({ ...user.info.schoolInfos?.[0], ...forms });
+        data.schoolLoading = true;
+        message.success('修改成功');
+        data.disabled = true;
+      });
+    };
+
+    const registerUrl = () => {
+      const queryStr = `tenantId=${user.info.schoolInfos?.[0]?.tenantId}&schoolId=${user.info.schoolInfos?.[0]?.id}&schoolName=${user.info.schoolInfos?.[0]?.name}`;
+      const url =
+        `${location.origin}/classroom-app/#/teaher-register?` + queryStr;
+      console.log(url);
+      return url;
+    };
+
+    const copyTo = (text: string) => {
+      const input = document.createElement('input');
+      input.value = text;
+      document.body.appendChild(input);
+      input.select();
+      input.setSelectionRange(0, input.value.length);
+      document.execCommand('Copy');
+      document.body.removeChild(input);
+      message.success('复制成功');
+    };
+    return () => (
+      <div class={styles.schoolInfo}>
+        <NForm
+          ref={formRef}
+          class={styles.formWrap}
+          model={forms}
+          style={{ padding: '30px 0' }}
+          disabled={data.disabled}>
+          <NSpace size={[30, 20]}>
+            <div class={styles.logo}>
+              <NImage
+                previewDisabled={false}
+                src={forms.logo}
+                objectFit="contain"
+              />
+              <div
+                style={{ display: data.disabled ? 'none' : '' }}
+                class={styles.changeHead}>
+                修改头像
+                {data.schoolLoading && (
+                  <UploadFile
+                    class={[styles.uploadFile]}
+                    cropper
+                    onUpdate:fileList={val => {
+                      forms.logo = val;
+                    }}
+                  />
+                )}
+              </div>
+            </div>
+            <NFormItem
+              label="学校名称"
+              path="name"
+              showRequireMark={false}
+              rule={[
+                { required: true, message: '请填写学校名称', trigger: 'blur' }
+              ]}>
+              <NInput
+                bordered={!data.disabled}
+                maxlength={20}
+                v-model:value={forms.name}
+              />
+            </NFormItem>
+            <NFormItem label="城区">
+              {!data.oldLoading && (
+                <NCascader
+                  placeholder="请选择城区"
+                  bordered={!data.disabled}
+                  options={formOptions.areaList}
+                  labelField="name"
+                  valueField="code"
+                  childrenField="areas"
+                  checkStrategy="child"
+                  expandTrigger="hover"
+                  defaultValue={
+                    user.info.schoolInfos?.[0]?.regionCode ||
+                    user.info.schoolInfos?.[0]?.cityCode ||
+                    user.info.schoolInfos?.[0]?.provinceCode
+                  }
+                  onUpdate:value={(val: any, option: any, pathValues: any) => {
+                    forms.provinceCode = pathValues[0]?.code;
+                    forms.cityCode = pathValues[1]?.code;
+                    forms.regionCode = pathValues[2]?.code;
+                  }}
+                />
+              )}
+            </NFormItem>
+            <NFormItem>
+              {data.disabled ? (
+                <NSpace class={styles.btnList} align="center" justify="end">
+                  <NButton
+                    class={styles.btn}
+                    color="#f24433"
+                    onClick={() => {
+                      data.oldTecherform = Object.assign({}, forms);
+                      data.disabled = false;
+                    }}>
+                    修改信息
+                  </NButton>
+                </NSpace>
+              ) : (
+                <NSpace class={styles.btnList} align="center" justify="end">
+                  <NButton
+                    class={styles.btn}
+                    onClick={() => {
+                      Object.assign(forms, data.oldTecherform);
+                      data.disabled = true;
+                      data.oldLoading = true;
+                      nextTick(() => {
+                        data.oldLoading = false;
+                      });
+                    }}>
+                    取消
+                  </NButton>
+                  <NButton
+                    class={styles.btn}
+                    loading={!data.schoolLoading}
+                    type="primary"
+                    onClick={() => changeSchoolInfo()}>
+                    完成
+                  </NButton>
+                </NSpace>
+              )}
+            </NFormItem>
+          </NSpace>
+        </NForm>
+
+        <NSpace style={{ padding: '0 0 32px' }}>
+          <NButton
+            focusable={false}
+            {...{ id: 'teacher-0' }}
+            type="primary"
+            renderIcon={() => <NIcon component={<Add />} />}
+            onClick={() => (data.modal = true)}>
+            添加老师
+          </NButton>
+          <NButton
+            focusable={false}
+            {...{ id: 'teacher-1' }}
+            type="primary"
+            onClick={() => (data.qrModal = true)}>
+            老师注册二维码
+          </NButton>
+        </NSpace>
+
+        <NDataTable
+          v-slots={{
+            empty: () => <TheEmpty></TheEmpty>
+          }}
+          loading={data.loading}
+          columns={columns()}
+          data={data.dataList}></NDataTable>
+
+        <NModal
+          class={styles.addTeacher}
+          v-model:show={data.modal}
+          title="添加老师"
+          preset="dialog"
+          showIcon={false}>
+          <AddTeacher
+            areaList={formOptions.areaList}
+            onClose={() => {
+              data.modal = false;
+              getList();
+            }}
+          />
+        </NModal>
+
+        {data.qrModal ? (
+          <div v-model:show={data.qrModal} class="n-modal-mask">
+            <AddteacherModel
+              onClose={() => {
+                data.qrModal = false;
+              }}></AddteacherModel>
+          </div>
+        ) : null}
+        {showGuide.value ? <TeacherGuide></TeacherGuide> : null}
+
+        <NModal
+          v-model:show={data.changeVisiable}
+          preset="card"
+          class={['modalTitle', styles.removeVisiable1]}
+          title={'转交管理员'}>
+          <TheMessageDialog
+            content={`<p style="text-align: left;">转交管理员后,您当前账号将无法查看和更改学校信息,请确认是否转交给<span style="color: #198CFE">【${data.activeRow.nickname}】</span></p>`}
+            cancelButtonText="取消"
+            confirmButtonText="确认"
+            loading={data.messageLoading}
+            onClose={() => (data.changeVisiable = false)}
+            onConfirm={onChangeManage}
+          />
+        </NModal>
+      </div>
+    );
+  }
+});

+ 56 - 50
src/views/setting/index.tsx

@@ -1,50 +1,56 @@
-import { defineComponent, ref, watch } from 'vue';
-import styles from './index.module.less';
-import { NTabs, NTabPane } from 'naive-ui';
-import PersonInfo from './components/personInfo';
-import SchoolInfo from './components/schoolInfo/index';
-import { useUserStore } from '/src/store/modules/users';
-import { useRoute } from 'vue-router';
-import { eventGlobal } from '/src/utils';
-export default defineComponent({
-  name: 'base-setting',
-  setup(props, { emit, attrs }) {
-    const activeTab = ref('person' as any);
-    const user = useUserStore();
-    const route = useRoute();
-    if (route.query.activeTab) {
-      activeTab.value = route.query.activeTab;
-      eventGlobal.emit('base-setting-emit', activeTab.value);
-    }
-    watch(
-      () => route.query.activeTab,
-      val => {
-        activeTab.value = val;
-        eventGlobal.emit('base-setting-emit', val);
-      }
-    );
-    return () => (
-      <div class={styles.listWrap}>
-        <NTabs
-          class={styles.customTabs}
-          v-model:value={activeTab.value}
-          size="large"
-          // animated
-          pane-wrapper-style="margin: 0 -4px"
-          pane-style="padding-left: 4px; padding-right: 4px; box-sizing: border-box;"
-          onUpdate:value={(val: any) => {
-            eventGlobal.emit('base-setting-emit', val);
-          }}>
-          <NTabPane name="person" tab="个人信息">
-            <PersonInfo></PersonInfo>
-          </NTabPane>
-          {user.info.isSuperAdmin && (
-            <NTabPane name="school" tab="学校设置">
-              <SchoolInfo />
-            </NTabPane>
-          )}
-        </NTabs>
-      </div>
-    );
-  }
-});
+import { defineComponent, ref, watch } from 'vue';
+import styles from './index.module.less';
+import { NTabs, NTabPane } from 'naive-ui';
+import PersonInfo from './components/personInfo';
+import SchoolInfo from './components/schoolInfo/index';
+import { useUserStore } from '/src/store/modules/users';
+import { useRoute } from 'vue-router';
+import { eventGlobal } from '/src/utils';
+export default defineComponent({
+  name: 'base-setting',
+  setup(props, { emit, attrs }) {
+    const activeTab = ref('person' as any);
+    const user = useUserStore();
+    const route = useRoute();
+    if (route.query.activeTab) {
+      activeTab.value = route.query.activeTab;
+      eventGlobal.emit('base-setting-emit', activeTab.value);
+    }
+    watch(
+      () => route.query.activeTab,
+      val => {
+        activeTab.value = val;
+        eventGlobal.emit('base-setting-emit', val);
+      }
+    );
+
+    // 切换tab
+    const onChangeTab = (value: string) => {
+      if (!value) return;
+      activeTab.value = value;
+    };
+    return () => (
+      <div class={styles.listWrap}>
+        <NTabs
+          class={styles.customTabs}
+          v-model:value={activeTab.value}
+          size="large"
+          // animated
+          pane-wrapper-style="margin: 0 -4px"
+          pane-style="padding-left: 4px; padding-right: 4px; box-sizing: border-box;"
+          onUpdate:value={(val: any) => {
+            eventGlobal.emit('base-setting-emit', val);
+          }}>
+          <NTabPane name="person" tab="个人信息">
+            <PersonInfo></PersonInfo>
+          </NTabPane>
+          {user.info.isSuperAdmin && (
+            <NTabPane name="school" tab="学校设置">
+              <SchoolInfo onChangeTab={onChangeTab} />
+            </NTabPane>
+          )}
+        </NTabs>
+      </div>
+    );
+  }
+});