Browse Source

Merge branch 'iteration-20240417-subject' into jenkins

lex 11 months ago
parent
commit
ef87533eae

+ 441 - 429
src/styles/index.less

@@ -1,430 +1,442 @@
-* {
-  padding: 0;
-  margin: 0;
-  border: 0;
-  box-sizing: border-box;
-}
-
-
-#app {
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-  color: #333;
-  min-height: 100vh;
-
-}
-
-body {
-  user-select: none;
-  background-color: #f1f5ff;
-  overflow: hidden;
-}
-
-body>.n-drawer-container-relative {
-  position: relative !important;
-}
-
-// 搜索框前面放大镜样式重置
-.icon-search-input {
-  display: inline-block;
-  width: max(16px, 14Px);
-  height: max(16px, 14Px);
-  background: url('../common/images/icon_search.png') no-repeat center;
-  background-size: contain;
-}
-
-.n-input:not(.n-input--disabled).n-input--focus {
-  .icon-search-input {
-    background: url('../common/images/icon_searchActive.png') no-repeat center;
-    background-size: contain;
-  }
-}
-
-// 初始化弹窗关闭的默认状态
-// .n-base-close:not(.n-base-close--disabled):focus::before {
-//   background-color: transparent;
-// }
-
-.n-base-select-menu .n-base-select-option {
-  font-size: max(15px, 12Px);
-}
-
-.n-popselect-menu {
-  --n-option-height: 38Px !important;
-}
-
-@font-face {
-  font-family: 'dotfont';
-  /* Project id  */
-  src: url('../common/text-security-disc.woff') format('woff');
-}
-
-.cr-ellipsis {
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-}
-
-.fade-enter-active,
-.fade-leave-active {
-  transition: opacity 0.5s ease;
-}
-
-.fade-enter-from,
-.fade-leave-to {
-  opacity: 0;
-}
-
-::-webkit-scrollbar {
-  width: 8px;
-  height: 12px;
-  background-color: #fff;
-}
-
-::-webkit-scrollbar-thumb {
-  display: block;
-  min-height: 12px;
-  min-width: 8px;
-  border-radius: 6px;
-  background-color: rgb(217, 217, 217);
-}
-
-::-webkit-scrollbar-thumb:hover {
-  display: block;
-  min-height: 12px;
-  min-width: 8px;
-  border-radius: 6px;
-  background-color: rgb(159, 159, 159);
-}
-
-.searchBtn {
-  // width: 90px;
-  // height: 43px;
-  background: #198cfe;
-  border-radius: 8px;
-  // line-height: 41px;
-  font-weight: 600 !important;
-  // font-size: max(18px, 13Px);
-}
-
-.resetBtn {
-  // width: 90px;
-  border-radius: 8px;
-  font-weight: 600 !important;
-  // font-size: max(18px, 13Px);
-}
-
-.resetBtn,
-.searchBtn {
-  --n-padding: 0 28px !important;
-}
-
-// .n-data-table {
-//   border-radius: 10px 10px 0 0;
-//   overflow: hidden;
-// }
-
-// .n-data-table-thead {
-//   height: 54px;
-//   line-height: 54px;
-// }
-
-// .n-data-table-th {
-//   padding: 0 20px !important;
-//   background-color: #f7f7f8 !important;
-//   color: rgba(0, 0, 0, 0.88) !important;
-
-//   .n-data-table-th__title {
-//     font-weight: 600;
-//   }
-// }
-
-// .n-data-table-tr {
-//   .n-data-table-td {
-//     padding-left: 20px;
-
-//     color: #333333;
-//     font-size: 14px;
-
-//     .n-button__content {
-//       font-size: 14px;
-//       color: #1677ff;
-//     }
-//   }
-// }
-
-:global {
-  .n-form-item .n-form-item-label {
-    color: #777;
-  }
-
-  .n-button {
-    border-radius: 8px;
-  }
-
-
-}
-
-.n-data-table-th__title-wrapper {
-  &::after {
-    content: '';
-    width: 1px;
-    height: 22px;
-    background: #ebebeb;
-
-    &:nth-last-child(1) {
-      display: none;
-    }
-  }
-}
-
-.n-data-table-th--last {
-  .n-data-table-th__title-wrapper {
-    &::after {
-      content: '';
-      width: 0px;
-      height: 22px;
-      background: #ebebeb;
-    }
-  }
-}
-
-// 给弹窗设置标题的基础样式
-.modalTitle {
-  border-radius: 16px;
-
-  // overflow: hidden;
-
-  &.background {
-    .n-card-header {
-      background: #f5f6fa;
-      font-weight: 600 !important;
-      overflow: hidden;
-    }
-  }
-
-  .n-card-header {
-    border-radius: 16px 16px 0 0;
-    position: relative;
-    padding: 20px 18px;
-    text-align: center;
-    background: #fff;
-    font-size: 22px;
-    font-weight: 600;
-    color: #131415;
-    line-height: 30px;
-  }
-
-  .n-card-header__close {
-    position: absolute;
-    right: 18px;
-    z-index: 99;
-  }
-
-  .n-card__content {
-    padding: 0;
-  }
-}
-
-.favitor-enter-active,
-.favitor-leave-active {
-  // transition: all 0.5s cubic-bezier(0.18, 0.89, 0, 1.29);
-  transition: all .3s ease-in-out;
-}
-
-.favitor-enter-from,
-.favitor-leave-to {
-  transform: scale(1.4);
-  opacity: 0.1;
-}
-
-@font-face {
-  font-family: 'DINA';
-  src: url('../common/DIN_Alternate_Bold.ttf');
-}
-
-:root {
-  --product-color: #3044ca;
-}
-
-// .n-button--primary-type {
-//   color: #1677ff !important;
-// }
-::-webkit-input-placeholder {
-  /* WebKit browsers */
-
-  color: rgba(0, 0, 0, 0.4);
-}
-
-:-moz-placeholder {
-  /* Mozilla Firefox 4 to 18 */
-
-  color: rgba(0, 0, 0, 0.4);
-}
-
-::-moz-placeholder {
-  /* Mozilla Firefox 19+ */
-
-  color: rgba(0, 0, 0, 0.4);
-}
-
-:-ms-input-placeholder {
-  /* Internet Explorer 10+ */
-
-  color: rgba(0, 0, 0, 0.4);
-}
-
-@keyframes TadaNum {
-  0% {
-    transform: rotate(0);
-    transform: rotate(0);
-  }
-
-  10%,
-  20% {
-    transform: rotate(-6deg);
-    transform: rotate(-6deg);
-  }
-
-  30%,
-  50%,
-  70%,
-  90% {
-    transform: rotate(6deg);
-    transform: rotate(6deg);
-  }
-
-  40%,
-  60%,
-  80% {
-    transform: rotate(-6deg);
-    transform: rotate(-6deg);
-  }
-
-  100% {
-    transform: rotate(0);
-    transform: rotate(0);
-  }
-}
-
-/* 列表动画 start */
-.list-move,
-/* 对移动中的元素应用的过渡 */
-.list-enter-active,
-.list-leave-active {
-  transition: all 0.5s ease;
-}
-
-.list-enter-from,
-.list-leave-to {
-  opacity: 0;
-  transform: translateX(30px);
-}
-
-// 拖动时
-.sortable-ghost {
-  opacity: 0.7;
-}
-
-.flip-list-move {
-  transition: transform 0.5s;
-}
-
-.no-move {
-  transition: transform 0s;
-}
-
-
-.n-data-table .n-data-table-th {
-
-  background: #F7F7F8;
-  color: rgba(113, 113, 114, 1) !important;
-  border: none;
-  min-height: 54px;
-  font-size: max(15px, 12Px);
-}
-
-.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: max(15px, 12Px);
-}
-
-.n-tooltip {
-  --n-padding: 6px 12px !important;
-  --n-border-radius: 6px !important;
-
-  .n-popover__content {
-    font-size: max(14px, 12Px);
-  }
-}
-
-
-.n-base-close:not(.n-base-close--disabled):active::before,
-.n-base-close:not(.n-base-close--disabled):focus::before {
-  background-color: transparent !important;
-}
-
-
-.body .n-modal-mask {
-  background-color: transparent !important;
-}
-
-// 设置图片弹窗工具预览
-.n-image-preview-toolbar .n-base-icon {
-  margin: 0 8px;
-  padding: 0;
-}
-
-.n-breadcrumb .n-breadcrumb-item {
-  font-size: max(16px, 12Px) !important;
-}
-
-.n-base-selection,
-.n-input,
-.n-input-group-label {
-  --n-height: max(40px, 36Px) !important;
-  --n-border-radius: 8px !important;
-  font-size: max(15px, 13Px) !important;
-}
-
-.n-button {
-  font-size: max(18px, 13Px);
-  --n-height: max(40px, 36Px) !important;
-}
-
-.n-base-selection-input,
-.n-input .n-input__input-el,
-.n-input .n-input__textarea-el {
-  font-size: max(15px, 13Px) !important;
-}
-
-.n-base-selection .n-base-selection-label .n-base-selection-label__render-label {
-  font-size: max(15px, 13Px) !important;
-}
-
-.n-select-menu .n-button {
-  --n-height: 28px !important;
-}
-
-.n-form-item-label__text {
-  font-size: max(15px, 13Px);
-}
-
-.n-date-panel {
-
-  .n-date-panel-actions__suffix,
-  .n-time-picker-panel {
-    .n-button {
-      font-size: 12Px;
-      height: 32px !important;
-      line-height: 32px;
-      padding: 0 13px !important;
-      border-radius: 6px;
-    }
-  }
+* {
+  padding: 0;
+  margin: 0;
+  border: 0;
+  box-sizing: border-box;
+}
+
+
+#app {
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  color: #333;
+  min-height: 100vh;
+
+}
+
+body {
+  user-select: none;
+  background-color: #f1f5ff;
+  overflow: hidden;
+}
+
+body>.n-drawer-container-relative {
+  position: relative !important;
+}
+
+// 搜索框前面放大镜样式重置
+.icon-search-input {
+  display: inline-block;
+  width: max(16px, 14Px);
+  height: max(16px, 14Px);
+  background: url('../common/images/icon_search.png') no-repeat center;
+  background-size: contain;
+}
+
+.n-input:not(.n-input--disabled).n-input--focus {
+  .icon-search-input {
+    background: url('../common/images/icon_searchActive.png') no-repeat center;
+    background-size: contain;
+  }
+}
+
+// 初始化弹窗关闭的默认状态
+// .n-base-close:not(.n-base-close--disabled):focus::before {
+//   background-color: transparent;
+// }
+
+.n-base-select-menu .n-base-select-option {
+  font-size: max(15px, 12Px);
+}
+
+.n-popselect-menu {
+  --n-option-height: 38Px !important;
+}
+
+@font-face {
+  font-family: 'dotfont';
+  /* Project id  */
+  src: url('../common/text-security-disc.woff') format('woff');
+}
+
+.cr-ellipsis {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+
+.fade-enter-active,
+.fade-leave-active {
+  transition: opacity 0.5s ease;
+}
+
+.fade-enter-from,
+.fade-leave-to {
+  opacity: 0;
+}
+
+::-webkit-scrollbar {
+  width: 8px;
+  height: 12px;
+  background-color: #fff;
+}
+
+::-webkit-scrollbar-thumb {
+  display: block;
+  min-height: 12px;
+  min-width: 8px;
+  border-radius: 6px;
+  background-color: rgb(217, 217, 217);
+}
+
+::-webkit-scrollbar-thumb:hover {
+  display: block;
+  min-height: 12px;
+  min-width: 8px;
+  border-radius: 6px;
+  background-color: rgb(159, 159, 159);
+}
+
+.searchBtn {
+  // width: 90px;
+  // height: 43px;
+  background: #198cfe;
+  border-radius: 8px;
+  // line-height: 41px;
+  font-weight: 600 !important;
+  // font-size: max(18px, 13Px);
+}
+
+.resetBtn {
+  // width: 90px;
+  border-radius: 8px;
+  font-weight: 600 !important;
+  // font-size: max(18px, 13Px);
+}
+
+.resetBtn,
+.searchBtn {
+  --n-padding: 0 28px !important;
+}
+
+// .n-data-table {
+//   border-radius: 10px 10px 0 0;
+//   overflow: hidden;
+// }
+
+// .n-data-table-thead {
+//   height: 54px;
+//   line-height: 54px;
+// }
+
+// .n-data-table-th {
+//   padding: 0 20px !important;
+//   background-color: #f7f7f8 !important;
+//   color: rgba(0, 0, 0, 0.88) !important;
+
+//   .n-data-table-th__title {
+//     font-weight: 600;
+//   }
+// }
+
+// .n-data-table-tr {
+//   .n-data-table-td {
+//     padding-left: 20px;
+
+//     color: #333333;
+//     font-size: 14px;
+
+//     .n-button__content {
+//       font-size: 14px;
+//       color: #1677ff;
+//     }
+//   }
+// }
+
+:global {
+  .n-form-item .n-form-item-label {
+    color: #777;
+  }
+
+  .n-button {
+    border-radius: 8px;
+  }
+
+
+}
+
+.n-cascader-submenu-wrapper {
+
+  .n-scrollbar>.n-scrollbar-rail.n-scrollbar-rail--vertical,
+  .n-scrollbar+.n-scrollbar-rail.n-scrollbar-rail--vertical {
+    right: 2Px;
+  }
+
+  .n-cascader-option__suffix {
+    padding-right: 12Px !important;
+  }
+}
+
+.n-data-table-th__title-wrapper {
+  &::after {
+    content: '';
+    width: 1px;
+    height: 22px;
+    background: #ebebeb;
+
+    &:nth-last-child(1) {
+      display: none;
+    }
+  }
+}
+
+.n-data-table-th--last {
+  .n-data-table-th__title-wrapper {
+    &::after {
+      content: '';
+      width: 0px;
+      height: 22px;
+      background: #ebebeb;
+    }
+  }
+}
+
+// 给弹窗设置标题的基础样式
+.modalTitle {
+  border-radius: 16px;
+
+  // overflow: hidden;
+
+  &.background {
+    .n-card-header {
+      background: #f5f6fa;
+      font-weight: 600 !important;
+      overflow: hidden;
+    }
+  }
+
+  .n-card-header {
+    border-radius: 16px 16px 0 0;
+    position: relative;
+    padding: 20px 18px;
+    text-align: center;
+    background: #fff;
+    font-size: 22px;
+    font-weight: 600;
+    color: #131415;
+    line-height: 30px;
+  }
+
+  .n-card-header__close {
+    position: absolute;
+    right: 18px;
+    z-index: 99;
+  }
+
+  .n-card__content {
+    padding: 0;
+  }
+}
+
+.favitor-enter-active,
+.favitor-leave-active {
+  // transition: all 0.5s cubic-bezier(0.18, 0.89, 0, 1.29);
+  transition: all .3s ease-in-out;
+}
+
+.favitor-enter-from,
+.favitor-leave-to {
+  transform: scale(1.4);
+  opacity: 0.1;
+}
+
+@font-face {
+  font-family: 'DINA';
+  src: url('../common/DIN_Alternate_Bold.ttf');
+}
+
+:root {
+  --product-color: #3044ca;
+}
+
+// .n-button--primary-type {
+//   color: #1677ff !important;
+// }
+::-webkit-input-placeholder {
+  /* WebKit browsers */
+
+  color: rgba(0, 0, 0, 0.4);
+}
+
+:-moz-placeholder {
+  /* Mozilla Firefox 4 to 18 */
+
+  color: rgba(0, 0, 0, 0.4);
+}
+
+::-moz-placeholder {
+  /* Mozilla Firefox 19+ */
+
+  color: rgba(0, 0, 0, 0.4);
+}
+
+:-ms-input-placeholder {
+  /* Internet Explorer 10+ */
+
+  color: rgba(0, 0, 0, 0.4);
+}
+
+@keyframes TadaNum {
+  0% {
+    transform: rotate(0);
+    transform: rotate(0);
+  }
+
+  10%,
+  20% {
+    transform: rotate(-6deg);
+    transform: rotate(-6deg);
+  }
+
+  30%,
+  50%,
+  70%,
+  90% {
+    transform: rotate(6deg);
+    transform: rotate(6deg);
+  }
+
+  40%,
+  60%,
+  80% {
+    transform: rotate(-6deg);
+    transform: rotate(-6deg);
+  }
+
+  100% {
+    transform: rotate(0);
+    transform: rotate(0);
+  }
+}
+
+/* 列表动画 start */
+.list-move,
+/* 对移动中的元素应用的过渡 */
+.list-enter-active,
+.list-leave-active {
+  transition: all 0.5s ease;
+}
+
+.list-enter-from,
+.list-leave-to {
+  opacity: 0;
+  transform: translateX(30px);
+}
+
+// 拖动时
+.sortable-ghost {
+  opacity: 0.7;
+}
+
+.flip-list-move {
+  transition: transform 0.5s;
+}
+
+.no-move {
+  transition: transform 0s;
+}
+
+
+.n-data-table .n-data-table-th {
+
+  background: #F7F7F8;
+  color: rgba(113, 113, 114, 1) !important;
+  border: none;
+  min-height: 54px;
+  font-size: max(15px, 12Px);
+}
+
+.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: max(15px, 12Px);
+}
+
+.n-tooltip {
+  --n-padding: 6px 12px !important;
+  --n-border-radius: 6px !important;
+
+  .n-popover__content {
+    font-size: max(14px, 12Px);
+  }
+}
+
+
+.n-base-close:not(.n-base-close--disabled):active::before,
+.n-base-close:not(.n-base-close--disabled):focus::before {
+  background-color: transparent !important;
+}
+
+
+.body .n-modal-mask {
+  background-color: transparent !important;
+}
+
+// 设置图片弹窗工具预览
+.n-image-preview-toolbar .n-base-icon {
+  margin: 0 8px;
+  padding: 0;
+}
+
+.n-breadcrumb .n-breadcrumb-item {
+  font-size: max(16px, 12Px) !important;
+}
+
+.n-base-selection,
+.n-input,
+.n-input-group-label {
+  --n-height: max(40px, 36Px) !important;
+  --n-border-radius: 8px !important;
+  font-size: max(15px, 13Px) !important;
+}
+
+.n-button {
+  font-size: max(18px, 13Px);
+  --n-height: max(40px, 36Px) !important;
+}
+
+.n-base-selection-input,
+.n-input .n-input__input-el,
+.n-input .n-input__textarea-el {
+  font-size: max(15px, 13Px) !important;
+}
+
+.n-base-selection .n-base-selection-label .n-base-selection-label__render-label {
+  font-size: max(15px, 13Px) !important;
+}
+
+.n-select-menu .n-button {
+  --n-height: 28px !important;
+}
+
+.n-form-item-label__text {
+  font-size: max(15px, 13Px);
+}
+
+.n-date-panel {
+
+  .n-date-panel-actions__suffix,
+  .n-time-picker-panel {
+    .n-button {
+      font-size: 12Px;
+      height: 32px !important;
+      line-height: 32px;
+      padding: 0 13px !important;
+      border-radius: 6px;
+    }
+  }
 }

+ 721 - 721
src/views/classList/index.tsx

@@ -1,721 +1,721 @@
-import { defineComponent, reactive, onMounted, ref } from 'vue';
-import styles from './index.module.less';
-import {
-  NButton,
-  NCascader,
-  NDataTable,
-  NForm,
-  NFormItem,
-  NImage,
-  NModal,
-  NSpace,
-  useMessage
-} from 'naive-ui';
-import SearchInput from '@/components/searchInput';
-import CSelect from '@/components/CSelect';
-import Pagination from '@/components/pagination';
-import { classGroupList, deleteClass, getSubject, addGroup } from './api';
-import CreateClass from './modals/createClass';
-import RestStudentBox from './modals/restStudentBox';
-import { getgradeNumList, classArray } from './contants';
-import add from '@/views/studentList/images/add.png';
-import ClassGuide from '@/custom-plugins/guide-page/class-guide';
-import { useRoute, useRouter } from 'vue-router';
-import TheEmpty from '/src/components/TheEmpty';
-import TheTooltip from '/src/components/TheTooltip';
-import PreviewWindow from '../preview-window';
-import ResetSubject from './modals/resetSubject';
-import UpdateSubject from './modals/updateSubject';
-import { getGradeLevelList, getGradeYearList } from '../home/api';
-import { initCache, setCache } from '/src/hooks/use-async';
-import AddStudentModel from '../studentList/modals/addStudentModel';
-import { useUserStore } from '/src/store/modules/users';
-import { useCatchStore } from '/src/store/modules/catchData';
-export default defineComponent({
-  name: 'class-classList',
-  setup() {
-    const catchData = useCatchStore();
-    const users = useUserStore();
-    const state = reactive({
-      searchForm: {
-        keyword: null as any,
-        currentClass: '',
-        currentGradeNum: '',
-        instrumentId: '',
-        gradeYear: '',
-        gradeLevel: ''
-      },
-      orchestraType: null,
-      courseTypeCode: null,
-      loading: false,
-      pagination: {
-        page: 1,
-        rows: 10,
-        pageTotal: 6
-      },
-      gradeNumList: [] as any,
-      tableList: [] as any,
-      studentVisible: false,
-      activeRow: null as any,
-      showaddClass: false,
-      goCourseVisiable: false,
-      removeVisiable: false,
-      removeRow: {} as any,
-      previewModal: false,
-      previewParams: {} as any,
-      lastCourse: null as any,
-      groupBtnLoading: false, // 按钮是否在请求中
-      // subjectList: [] as any,
-      showResetClass: false,
-      showSubjectClass: false,
-      groupVisiable: false,
-      popSelectYearList: [] as any,
-      popSelectLevelList: [] as any,
-      addStudentVisible: false
-    });
-    const formRef = ref();
-    const message = useMessage();
-    const router = useRouter();
-    const route = useRoute();
-    const search = () => {
-      state.pagination.page = 1;
-      getList();
-      setCache({ current: state.searchForm, saveKey: route.path });
-    };
-    const showGuide = ref(false);
-    state.gradeNumList = getgradeNumList();
-    const onReset = () => {
-      state.searchForm = {
-        keyword: null as any,
-        currentClass: '' as any,
-        currentGradeNum: '' as any,
-        instrumentId: '' as any,
-        gradeYear: '' as any,
-        gradeLevel: ''
-      };
-      if (state.popSelectYearList.length > 1) {
-        state.searchForm.gradeYear = state.popSelectYearList[1].id;
-      }
-      getList();
-      setCache({ current: state.searchForm, saveKey: route.path });
-    };
-
-    const removeClass = async () => {
-      try {
-        await deleteClass({ ids: state.removeRow.id });
-        getList();
-        message.success(`删除成功`);
-        state.removeVisiable = false;
-      } catch (e) {
-        console.log(e);
-      }
-    };
-    const getList = async () => {
-      // classGroupList
-      state.loading = true;
-      try {
-        const res = await classGroupList({
-          ...state.searchForm,
-          ...state.pagination
-        });
-        state.tableList = res.data.rows;
-        state.pagination.pageTotal = res.data.total;
-        state.loading = false;
-
-        setTimeout(() => {
-          if (state.tableList.length > 0) {
-            showGuide.value = true;
-          }
-        }, 500);
-      } catch (e) {
-        state.loading = false;
-        console.log(e);
-      }
-    };
-    // const getSubjectList = async () => {
-    //   const res = await getSubject({ page: 1, rows: 9999 });
-    //   state.subjectList = res.data.rows.map((item: any) => {
-    //     return {
-    //       value: item.id,
-    //       label: item.name
-    //     };
-    //   });
-    //   state.subjectList.unshift({ value: '', label: '全部声部' });
-    // };
-    const columns = () => {
-      return [
-        {
-          title: '班级名称',
-          key: 'name'
-        },
-        {
-          title: '学年',
-          key: 'gradeYear'
-        },
-        {
-          title: '学级',
-          key: 'gradeLevel',
-          render(row: any) {
-            return row.gradeLevel ? `${row.gradeLevel}级` : '';
-          }
-        },
-        {
-          title: '班级乐器',
-          key: 'instrumentName'
-        },
-        {
-          title: '学生人数',
-          key: 'preStudentNum'
-        },
-        {
-          title: '上次学习',
-          key: 'lastStudy',
-          width: '20%',
-          render(row: any) {
-            return row.lastStudy ? (
-              <TheTooltip
-                maxWidth={300}
-                showContentWidth={300}
-                content={row.lastStudy}
-              />
-            ) : (
-              '--'
-            );
-          }
-        },
-        {
-          title: '操作',
-          key: 'id',
-
-          render(row: any, index: number) {
-            return (
-              <div>
-                <NSpace>
-                  {index == 0 ? (
-                    <div id="class-0">
-                      <NButton
-                        type="primary"
-                        text
-                        onClick={() => {
-                          router.push({
-                            path: '/classDetail',
-                            query: {
-                              name: row.name,
-                              id: row.id,
-                              gradeYear: row.gradeYear,
-                              upgradeFlag: row.upgradeFlag ? 1 : 0 // 是否为历史班
-                            }
-                          });
-                        }}>
-                        详情
-                      </NButton>
-                    </div>
-                  ) : (
-                    <NButton
-                      type="primary"
-                      text
-                      onClick={() => {
-                        router.push({
-                          path: '/classDetail',
-                          query: {
-                            name: row.name,
-                            id: row.id,
-                            gradeYear: row.gradeYear,
-                            upgradeFlag: row.upgradeFlag ? 1 : 0 // 是否为历史班
-                          }
-                        });
-                      }}>
-                      详情
-                    </NButton>
-                  )}
-                  <NButton
-                    type="primary"
-                    disabled={!row.upgradeFlag || row.instrumentId}
-                    text
-                    onClick={() => resetClassSubject(row)}>
-                    修改乐器
-                  </NButton>
-                  {index == 0 ? (
-                    <NButton
-                      type="primary"
-                      disabled={!row.upgradeFlag}
-                      {...{ id: 'class-1' }}
-                      text
-                      onClick={() => {
-                        startResetStudent(row);
-                      }}>
-                      学生调整
-                    </NButton>
-                  ) : (
-                    <NButton
-                      type="primary"
-                      disabled={!row.upgradeFlag}
-                      text
-                      onClick={() => {
-                        startResetStudent(row);
-                      }}>
-                      学生调整
-                    </NButton>
-                  )}
-                  {index == 0 ? (
-                    <NButton
-                      {...{ id: 'class-2' }}
-                      disabled={!row.upgradeFlag}
-                      type="primary"
-                      text
-                      onClick={() => classesBegin(row)}>
-                      开始上课
-                    </NButton>
-                  ) : (
-                    <NButton
-                      disabled={!row.upgradeFlag}
-                      type="primary"
-                      text
-                      onClick={() => classesBegin(row)}>
-                      开始上课
-                    </NButton>
-                  )}
-
-                  {/* <p
-                      style={{ color: '#EA4132', cursor: 'pointer' }}
-                      onClick={() => {
-                        state.removeVisiable = true;
-                        state.removeRow = row;
-                      }}>
-                      删除
-                    </p> */}
-                  {!(row.preStudentNum > 0) ? (
-                    <NButton
-                      type="error"
-                      color="#EA4132"
-                      textColor="#EA4132"
-                      text
-                      onClick={() => {
-                        state.removeVisiable = true;
-                        state.removeRow = row;
-                      }}>
-                      删除
-                    </NButton>
-                  ) : null}
-                  {row.imGroupId ? null : (
-                    <NButton
-                      type="primary"
-                      disabled={!row.upgradeFlag}
-                      text
-                      onClick={() => {
-                        createImgroup(row);
-                      }}>
-                      创建群聊
-                    </NButton>
-                  )}
-                  <NButton
-                    type="primary"
-                    disabled={!row.upgradeFlag}
-                    text
-                    onClick={() => {
-                      const { schoolInfos } = users.getUserInfo;
-                      const schoolId =
-                        schoolInfos.length > 0 ? schoolInfos[0].id : null;
-                      if (schoolId) {
-                        state.addStudentVisible = true;
-                        state.activeRow = {
-                          id: schoolId,
-                          classId: row.id,
-                          currentGradeNum: row.currentGradeNum,
-                          currentClass: row.currentClass,
-                          gradeYear: row.gradeYear
-                        };
-                      }
-                    }}>
-                    邀请学生
-                  </NButton>
-                </NSpace>
-              </div>
-            );
-          }
-        }
-      ];
-    };
-
-    const startResetStudent = (row: any) => {
-      state.activeRow = row;
-      state.studentVisible = true;
-    };
-
-    const classesBegin = async (row: any) => {
-      try {
-        // 判断是否有声部
-        if (row.instrumentId) {
-          //
-          // 声部先取上次上课的声部,如果没有则取班级上面的声部
-          router.push({
-            path: '/prepare-lessons',
-            query: {
-              lastUseCoursewareId: row.lessonCoursewareId,
-              unit: row.lessonCoursewareKnowledgeDetailId,
-              instrumentId: row.instrumentId,
-              courseScheduleSubjectId: row.courseScheduleSubjectId,
-              preStudentNum: row.preStudentNum,
-              name: row.name, // 班级名称
-              classGroupId: row.id // 班级编号
-            }
-          });
-        } else {
-          state.showSubjectClass = true;
-          state.activeRow = row;
-        }
-      } catch (e) {
-        console.log(e);
-      }
-    };
-
-    const resetClassSubject = (row: any) => {
-      state.activeRow = row;
-      state.showResetClass = true;
-    };
-    const createImgroup = async (row: any) => {
-      state.activeRow = row;
-      state.groupVisiable = true;
-    };
-
-    const submitGroup = async () => {
-      console.log(state.activeRow, 'row');
-      state.groupBtnLoading = true;
-      try {
-        await addGroup({ classGroupId: state.activeRow.id });
-        message.success('创建成功');
-        state.groupVisiable = false;
-        await getList();
-      } catch (e) {
-        console.log(e);
-      }
-      state.groupBtnLoading = false;
-    };
-
-    // 获取学年
-    const getYearList = async () => {
-      try {
-        const { data } = await getGradeYearList();
-        const temp = data || [];
-        temp.forEach((i: any) => {
-          i.name = i.name + '学年';
-        });
-        // temp.unshift({
-        //   id: '',
-        //   name: '全部学年'
-        // });
-        state.popSelectYearList = temp || [];
-        if (temp.length > 1 && !state.searchForm.gradeYear) {
-          state.searchForm.gradeYear = temp[1].id;
-        }
-      } catch {
-        //
-      }
-    };
-    // 获取学级
-    const getLevelList = async () => {
-      try {
-        const { data } = await getGradeLevelList();
-        const temp = data || [];
-        temp.forEach((i: any) => {
-          i.name = i.name + '级';
-        });
-        temp.unshift({
-          id: '',
-          name: '全部学级'
-        });
-        state.popSelectLevelList = temp || [];
-        if (temp.length > 0 && !state.searchForm.gradeLevel) {
-          state.searchForm.gradeLevel = temp[0].id;
-        }
-      } catch {
-        //
-      }
-    };
-
-    initCache({
-      current: state.searchForm,
-      callBack: (active: any) => {
-        state.searchForm = active;
-      }
-    });
-
-    onMounted(async () => {
-      state.loading = true;
-      await catchData.getSubjects();
-
-      // getSubjectList();
-      await getYearList();
-      await getLevelList();
-      await getList();
-
-      state.loading = false;
-    });
-    return () => (
-      <div class={styles.listWrap}>
-        <div class={styles.searchList}>
-          <NForm label-placement="left" inline ref={formRef}>
-            <NFormItem>
-              <SearchInput
-                {...{ placeholder: '请输入班级名称' }}
-                class={styles.searchInput}
-                searchWord={state.searchForm.keyword}
-                onChangeValue={(val: string) =>
-                  (state.searchForm.keyword = val)
-                }></SearchInput>
-            </NFormItem>
-            <NFormItem>
-              <CSelect
-                {...({
-                  options: state.popSelectYearList,
-                  placeholder: '选择学年',
-                  clearable: false,
-                  inline: true,
-                  labelField: 'name',
-                  valueField: 'id'
-                } as any)}
-                v-model:value={state.searchForm.gradeYear}></CSelect>
-            </NFormItem>
-            <NFormItem>
-              <CSelect
-                {...({
-                  options: state.popSelectLevelList,
-                  placeholder: '选择学级',
-                  clearable: true,
-                  inline: true,
-                  labelField: 'name',
-                  valueField: 'id'
-                } as any)}
-                v-model:value={state.searchForm.gradeLevel}></CSelect>
-            </NFormItem>
-
-            <NFormItem>
-              <CSelect
-                {...({
-                  options: state.gradeNumList,
-                  placeholder: '选择年级',
-                  clearable: true,
-                  inline: true
-                } as any)}
-                v-model:value={state.searchForm.currentGradeNum}></CSelect>
-            </NFormItem>
-            <NFormItem>
-              <CSelect
-                {...({
-                  options: classArray,
-                  placeholder: '选择班级',
-                  clearable: true,
-                  inline: true
-                } as any)}
-                v-model:value={state.searchForm.currentClass}></CSelect>
-            </NFormItem>
-            <NFormItem>
-              {/* <CSelect
-                {...({
-                  options: [
-                    { value: '', label: '全部声部' },
-                    ...catchData.getSubjectList
-                  ],
-                  placeholder: '选择乐器',
-                  clearable: true,
-                  inline: true
-                } as any)}
-                v-model:value={state.searchForm.instrumentId}></CSelect> */}
-              <NCascader
-                to="body"
-                placeholder="选择乐器"
-                options={[
-                  { value: '', label: '全部乐器' },
-                  ...catchData.getSubjectList
-                ]}
-                childrenField="instruments"
-                checkStrategy="child"
-                expandTrigger="hover"
-                showPath={false}
-                v-model:value={state.searchForm.instrumentId}
-                onUpdate:value={(val: any, option: any, pathValues: any) => {
-                  console.log(val, option, pathValues);
-                }}
-              />
-            </NFormItem>
-            <NFormItem>
-              <NSpace justify="end">
-                <NButton type="primary" class="searchBtn" onClick={search}>
-                  搜索
-                </NButton>
-                <NButton
-                  type="primary"
-                  ghost
-                  class="resetBtn"
-                  onClick={onReset}>
-                  重置
-                </NButton>
-              </NSpace>
-            </NFormItem>
-          </NForm>
-        </div>
-        <NButton
-          class={styles.addBtn}
-          type="primary"
-          onClick={() => (state.showaddClass = true)}
-          v-slots={{
-            icon: () => (
-              <>
-                <NImage
-                  class={styles.addBtnIcon}
-                  previewDisabled
-                  src={add}></NImage>
-              </>
-            )
-          }}>
-          创建班级
-        </NButton>
-        <div class={styles.tableWrap}>
-          <NDataTable
-            v-slots={{
-              empty: () => <TheEmpty></TheEmpty>
-            }}
-            class={styles.classTable}
-            loading={state.loading}
-            columns={columns()}
-            data={state.tableList}></NDataTable>
-          <Pagination
-            v-model:page={state.pagination.page}
-            v-model:pageSize={state.pagination.rows}
-            v-model:pageTotal={state.pagination.pageTotal}
-            onList={getList}
-            sync
-          />
-        </div>
-        <NModal
-          v-model:show={state.studentVisible}
-          preset="card"
-          class={['modalTitle background', styles.studentVisible]}
-          title={'学生调整'}>
-          <RestStudentBox
-            activeRow={state.activeRow}
-            onClose={() => (state.studentVisible = false)}
-            onGetList={() => getList()}></RestStudentBox>
-        </NModal>
-        <NModal
-          v-model:show={state.showaddClass}
-          style={{ width: '500px' }}
-          display-directive="if"
-          preset="card"
-          class={['modalTitle background']}
-          title={'创建班级'}>
-          <CreateClass
-            gradeYearList={state.popSelectYearList}
-            gradeNumList={state.gradeNumList}
-            classArray={classArray}
-            onGetList={() => getList()}
-            onClose={() => (state.showaddClass = false)}
-          />
-        </NModal>
-        <NModal
-          v-model:show={state.showResetClass}
-          style={{ width: '500px' }}
-          display-directive="if"
-          preset="card"
-          class={['modalTitle background']}
-          title={'修改乐器'}>
-          <ResetSubject
-            activeRow={state.activeRow}
-            onGetList={() => getList()}
-            onClose={() => (state.showResetClass = false)}
-          />
-        </NModal>
-
-        <NModal
-          v-model:show={state.showSubjectClass}
-          style={{ width: '500px' }}
-          preset="card"
-          class={['modalTitle background']}
-          title={'修改乐器'}>
-          {state.showSubjectClass ? (
-            <UpdateSubject
-              activeRow={state.activeRow}
-              onGetList={() => getList()}
-              onConfirm={(item: any) => {
-                //
-                router.push({
-                  path: '/prepare-lessons',
-                  query: {
-                    ...item
-                  }
-                });
-              }}
-              onClose={() => (state.showSubjectClass = false)}
-            />
-          ) : null}
-        </NModal>
-
-        {/* 上课弹窗 */}
-        <PreviewWindow
-          v-model:show={state.previewModal}
-          type="attend"
-          params={state.previewParams}
-        />
-
-        <NModal
-          v-model:show={state.removeVisiable}
-          preset="card"
-          class={['modalTitle', styles.removeVisiable]}
-          title={'删除班级'}>
-          <div class={styles.studentRemove}>
-            <p>
-              确定要删除班级么?
-              <span>删除班级信息将会清空</span>。
-            </p>
-
-            <NSpace class={styles.btnGroup} justify="center">
-              <NButton round type="primary" onClick={removeClass}>
-                确定
-              </NButton>
-              <NButton round onClick={() => (state.removeVisiable = false)}>
-                取消
-              </NButton>
-            </NSpace>
-          </div>
-        </NModal>
-
-        <NModal
-          v-model:show={state.groupVisiable}
-          preset="card"
-          class={['modalTitle', styles.removeVisiable]}
-          title={'创建群聊'}>
-          <div class={styles.studentRemove}>
-            <p style={{ textAlign: 'center' }}>是否创建班级群聊</p>
-
-            <NSpace class={styles.btnGroup} justify="center">
-              <NButton
-                round
-                type="primary"
-                onClick={submitGroup}
-                loading={state.groupBtnLoading}
-                disabled={state.groupBtnLoading}>
-                确定
-              </NButton>
-              <NButton round onClick={() => (state.groupVisiable = false)}>
-                取消
-              </NButton>
-            </NSpace>
-          </div>
-        </NModal>
-        {showGuide.value ? <ClassGuide></ClassGuide> : null}
-
-        {state.addStudentVisible ? (
-          <div
-            v-model:show={state.addStudentVisible}
-            class={['n-modal-mask', styles.popBox]}>
-            <AddStudentModel
-              activeRow={state.activeRow}
-              onClose={() => {
-                state.addStudentVisible = false;
-              }}></AddStudentModel>
-          </div>
-        ) : null}
-      </div>
-    );
-  }
-});
+import { defineComponent, reactive, onMounted, ref } from 'vue';
+import styles from './index.module.less';
+import {
+  NButton,
+  NCascader,
+  NDataTable,
+  NForm,
+  NFormItem,
+  NImage,
+  NModal,
+  NSpace,
+  useMessage
+} from 'naive-ui';
+import SearchInput from '@/components/searchInput';
+import CSelect from '@/components/CSelect';
+import Pagination from '@/components/pagination';
+import { classGroupList, deleteClass, getSubject, addGroup } from './api';
+import CreateClass from './modals/createClass';
+import RestStudentBox from './modals/restStudentBox';
+import { getgradeNumList, classArray } from './contants';
+import add from '@/views/studentList/images/add.png';
+import ClassGuide from '@/custom-plugins/guide-page/class-guide';
+import { useRoute, useRouter } from 'vue-router';
+import TheEmpty from '/src/components/TheEmpty';
+import TheTooltip from '/src/components/TheTooltip';
+import PreviewWindow from '../preview-window';
+import ResetSubject from './modals/resetSubject';
+import UpdateSubject from './modals/updateSubject';
+import { getGradeLevelList, getGradeYearList } from '../home/api';
+import { initCache, setCache } from '/src/hooks/use-async';
+import AddStudentModel from '../studentList/modals/addStudentModel';
+import { useUserStore } from '/src/store/modules/users';
+import { useCatchStore } from '/src/store/modules/catchData';
+export default defineComponent({
+  name: 'class-classList',
+  setup() {
+    const catchData = useCatchStore();
+    const users = useUserStore();
+    const state = reactive({
+      searchForm: {
+        keyword: null as any,
+        currentClass: '',
+        currentGradeNum: '',
+        instrumentId: '',
+        gradeYear: '',
+        gradeLevel: ''
+      },
+      orchestraType: null,
+      courseTypeCode: null,
+      loading: false,
+      pagination: {
+        page: 1,
+        rows: 10,
+        pageTotal: 6
+      },
+      gradeNumList: [] as any,
+      tableList: [] as any,
+      studentVisible: false,
+      activeRow: null as any,
+      showaddClass: false,
+      goCourseVisiable: false,
+      removeVisiable: false,
+      removeRow: {} as any,
+      previewModal: false,
+      previewParams: {} as any,
+      lastCourse: null as any,
+      groupBtnLoading: false, // 按钮是否在请求中
+      // subjectList: [] as any,
+      showResetClass: false,
+      showSubjectClass: false,
+      groupVisiable: false,
+      popSelectYearList: [] as any,
+      popSelectLevelList: [] as any,
+      addStudentVisible: false
+    });
+    const formRef = ref();
+    const message = useMessage();
+    const router = useRouter();
+    const route = useRoute();
+    const search = () => {
+      state.pagination.page = 1;
+      getList();
+      setCache({ current: state.searchForm, saveKey: route.path });
+    };
+    const showGuide = ref(false);
+    state.gradeNumList = getgradeNumList();
+    const onReset = () => {
+      state.searchForm = {
+        keyword: null as any,
+        currentClass: '' as any,
+        currentGradeNum: '' as any,
+        instrumentId: '' as any,
+        gradeYear: '' as any,
+        gradeLevel: ''
+      };
+      if (state.popSelectYearList.length > 1) {
+        state.searchForm.gradeYear = state.popSelectYearList[1].id;
+      }
+      getList();
+      setCache({ current: state.searchForm, saveKey: route.path });
+    };
+
+    const removeClass = async () => {
+      try {
+        await deleteClass({ ids: state.removeRow.id });
+        getList();
+        message.success(`删除成功`);
+        state.removeVisiable = false;
+      } catch (e) {
+        console.log(e);
+      }
+    };
+    const getList = async () => {
+      // classGroupList
+      state.loading = true;
+      try {
+        const res = await classGroupList({
+          ...state.searchForm,
+          ...state.pagination
+        });
+        state.tableList = res.data.rows;
+        state.pagination.pageTotal = res.data.total;
+        state.loading = false;
+
+        setTimeout(() => {
+          if (state.tableList.length > 0) {
+            showGuide.value = true;
+          }
+        }, 500);
+      } catch (e) {
+        state.loading = false;
+        console.log(e);
+      }
+    };
+    // const getSubjectList = async () => {
+    //   const res = await getSubject({ page: 1, rows: 9999 });
+    //   state.subjectList = res.data.rows.map((item: any) => {
+    //     return {
+    //       value: item.id,
+    //       label: item.name
+    //     };
+    //   });
+    //   state.subjectList.unshift({ value: '', label: '全部声部' });
+    // };
+    const columns = () => {
+      return [
+        {
+          title: '班级名称',
+          key: 'name'
+        },
+        {
+          title: '学年',
+          key: 'gradeYear'
+        },
+        {
+          title: '学级',
+          key: 'gradeLevel',
+          render(row: any) {
+            return row.gradeLevel ? `${row.gradeLevel}级` : '';
+          }
+        },
+        {
+          title: '班级乐器',
+          key: 'instrumentName'
+        },
+        {
+          title: '学生人数',
+          key: 'preStudentNum'
+        },
+        {
+          title: '上次学习',
+          key: 'lastStudy',
+          width: '20%',
+          render(row: any) {
+            return row.lastStudy ? (
+              <TheTooltip
+                maxWidth={300}
+                showContentWidth={300}
+                content={row.lastStudy}
+              />
+            ) : (
+              '--'
+            );
+          }
+        },
+        {
+          title: '操作',
+          key: 'id',
+
+          render(row: any, index: number) {
+            return (
+              <div>
+                <NSpace>
+                  {index == 0 ? (
+                    <div id="class-0">
+                      <NButton
+                        type="primary"
+                        text
+                        onClick={() => {
+                          router.push({
+                            path: '/classDetail',
+                            query: {
+                              name: row.name,
+                              id: row.id,
+                              gradeYear: row.gradeYear,
+                              upgradeFlag: row.upgradeFlag ? 1 : 0 // 是否为历史班
+                            }
+                          });
+                        }}>
+                        详情
+                      </NButton>
+                    </div>
+                  ) : (
+                    <NButton
+                      type="primary"
+                      text
+                      onClick={() => {
+                        router.push({
+                          path: '/classDetail',
+                          query: {
+                            name: row.name,
+                            id: row.id,
+                            gradeYear: row.gradeYear,
+                            upgradeFlag: row.upgradeFlag ? 1 : 0 // 是否为历史班
+                          }
+                        });
+                      }}>
+                      详情
+                    </NButton>
+                  )}
+                  <NButton
+                    type="primary"
+                    disabled={!row.upgradeFlag || row.instrumentId}
+                    text
+                    onClick={() => resetClassSubject(row)}>
+                    修改乐器
+                  </NButton>
+                  {index == 0 ? (
+                    <NButton
+                      type="primary"
+                      disabled={!row.upgradeFlag}
+                      {...{ id: 'class-1' }}
+                      text
+                      onClick={() => {
+                        startResetStudent(row);
+                      }}>
+                      学生调整
+                    </NButton>
+                  ) : (
+                    <NButton
+                      type="primary"
+                      disabled={!row.upgradeFlag}
+                      text
+                      onClick={() => {
+                        startResetStudent(row);
+                      }}>
+                      学生调整
+                    </NButton>
+                  )}
+                  {index == 0 ? (
+                    <NButton
+                      {...{ id: 'class-2' }}
+                      disabled={!row.upgradeFlag}
+                      type="primary"
+                      text
+                      onClick={() => classesBegin(row)}>
+                      开始上课
+                    </NButton>
+                  ) : (
+                    <NButton
+                      disabled={!row.upgradeFlag}
+                      type="primary"
+                      text
+                      onClick={() => classesBegin(row)}>
+                      开始上课
+                    </NButton>
+                  )}
+
+                  {/* <p
+                      style={{ color: '#EA4132', cursor: 'pointer' }}
+                      onClick={() => {
+                        state.removeVisiable = true;
+                        state.removeRow = row;
+                      }}>
+                      删除
+                    </p> */}
+                  {!(row.preStudentNum > 0) ? (
+                    <NButton
+                      type="error"
+                      color="#EA4132"
+                      textColor="#EA4132"
+                      text
+                      onClick={() => {
+                        state.removeVisiable = true;
+                        state.removeRow = row;
+                      }}>
+                      删除
+                    </NButton>
+                  ) : null}
+                  {row.imGroupId ? null : (
+                    <NButton
+                      type="primary"
+                      disabled={!row.upgradeFlag}
+                      text
+                      onClick={() => {
+                        createImgroup(row);
+                      }}>
+                      创建群聊
+                    </NButton>
+                  )}
+                  <NButton
+                    type="primary"
+                    disabled={!row.upgradeFlag}
+                    text
+                    onClick={() => {
+                      const { schoolInfos } = users.getUserInfo;
+                      const schoolId =
+                        schoolInfos.length > 0 ? schoolInfos[0].id : null;
+                      if (schoolId) {
+                        state.addStudentVisible = true;
+                        state.activeRow = {
+                          id: schoolId,
+                          classId: row.id,
+                          currentGradeNum: row.currentGradeNum,
+                          currentClass: row.currentClass,
+                          gradeYear: row.gradeYear
+                        };
+                      }
+                    }}>
+                    邀请学生
+                  </NButton>
+                </NSpace>
+              </div>
+            );
+          }
+        }
+      ];
+    };
+
+    const startResetStudent = (row: any) => {
+      state.activeRow = row;
+      state.studentVisible = true;
+    };
+
+    const classesBegin = async (row: any) => {
+      try {
+        // 判断是否有声部
+        if (row.instrumentId) {
+          //
+          // 声部先取上次上课的声部,如果没有则取班级上面的声部
+          router.push({
+            path: '/prepare-lessons',
+            query: {
+              lastUseCoursewareId: row.lessonCoursewareId,
+              unit: row.lessonCoursewareKnowledgeDetailId,
+              instrumentId: row.instrumentId,
+              courseScheduleSubjectId: row.courseScheduleSubjectId,
+              preStudentNum: row.preStudentNum,
+              name: row.name, // 班级名称
+              classGroupId: row.id // 班级编号
+            }
+          });
+        } else {
+          state.showSubjectClass = true;
+          state.activeRow = row;
+        }
+      } catch (e) {
+        console.log(e);
+      }
+    };
+
+    const resetClassSubject = (row: any) => {
+      state.activeRow = row;
+      state.showResetClass = true;
+    };
+    const createImgroup = async (row: any) => {
+      state.activeRow = row;
+      state.groupVisiable = true;
+    };
+
+    const submitGroup = async () => {
+      console.log(state.activeRow, 'row');
+      state.groupBtnLoading = true;
+      try {
+        await addGroup({ classGroupId: state.activeRow.id });
+        message.success('创建成功');
+        state.groupVisiable = false;
+        await getList();
+      } catch (e) {
+        console.log(e);
+      }
+      state.groupBtnLoading = false;
+    };
+
+    // 获取学年
+    const getYearList = async () => {
+      try {
+        const { data } = await getGradeYearList();
+        const temp = data || [];
+        temp.forEach((i: any) => {
+          i.name = i.name + '学年';
+        });
+        // temp.unshift({
+        //   id: '',
+        //   name: '全部学年'
+        // });
+        state.popSelectYearList = temp || [];
+        if (temp.length > 1 && !state.searchForm.gradeYear) {
+          state.searchForm.gradeYear = temp[1].id;
+        }
+      } catch {
+        //
+      }
+    };
+    // 获取学级
+    const getLevelList = async () => {
+      try {
+        const { data } = await getGradeLevelList();
+        const temp = data || [];
+        temp.forEach((i: any) => {
+          i.name = i.name + '级';
+        });
+        temp.unshift({
+          id: '',
+          name: '全部学级'
+        });
+        state.popSelectLevelList = temp || [];
+        if (temp.length > 0 && !state.searchForm.gradeLevel) {
+          state.searchForm.gradeLevel = temp[0].id;
+        }
+      } catch {
+        //
+      }
+    };
+
+    initCache({
+      current: state.searchForm,
+      callBack: (active: any) => {
+        state.searchForm = active;
+      }
+    });
+
+    onMounted(async () => {
+      state.loading = true;
+      await catchData.getSubjects();
+
+      // getSubjectList();
+      await getYearList();
+      await getLevelList();
+      await getList();
+
+      state.loading = false;
+    });
+    return () => (
+      <div class={styles.listWrap}>
+        <div class={styles.searchList}>
+          <NForm label-placement="left" inline ref={formRef}>
+            <NFormItem>
+              <SearchInput
+                {...{ placeholder: '请输入班级名称' }}
+                class={styles.searchInput}
+                searchWord={state.searchForm.keyword}
+                onChangeValue={(val: string) =>
+                  (state.searchForm.keyword = val)
+                }></SearchInput>
+            </NFormItem>
+            <NFormItem>
+              <CSelect
+                {...({
+                  options: state.popSelectYearList,
+                  placeholder: '选择学年',
+                  clearable: false,
+                  inline: true,
+                  labelField: 'name',
+                  valueField: 'id'
+                } as any)}
+                v-model:value={state.searchForm.gradeYear}></CSelect>
+            </NFormItem>
+            <NFormItem>
+              <CSelect
+                {...({
+                  options: state.popSelectLevelList,
+                  placeholder: '选择学级',
+                  clearable: true,
+                  inline: true,
+                  labelField: 'name',
+                  valueField: 'id'
+                } as any)}
+                v-model:value={state.searchForm.gradeLevel}></CSelect>
+            </NFormItem>
+
+            <NFormItem>
+              <CSelect
+                {...({
+                  options: state.gradeNumList,
+                  placeholder: '选择年级',
+                  clearable: true,
+                  inline: true
+                } as any)}
+                v-model:value={state.searchForm.currentGradeNum}></CSelect>
+            </NFormItem>
+            <NFormItem>
+              <CSelect
+                {...({
+                  options: classArray,
+                  placeholder: '选择班级',
+                  clearable: true,
+                  inline: true
+                } as any)}
+                v-model:value={state.searchForm.currentClass}></CSelect>
+            </NFormItem>
+            <NFormItem>
+              {/* <CSelect
+                {...({
+                  options: [
+                    { value: '', label: '全部声部' },
+                    ...catchData.getSubjectList
+                  ],
+                  placeholder: '选择乐器',
+                  clearable: true,
+                  inline: true
+                } as any)}
+                v-model:value={state.searchForm.instrumentId}></CSelect> */}
+              <NCascader
+                to="body"
+                placeholder="选择乐器"
+                options={[
+                  { value: '', label: '全部乐器' },
+                  ...catchData.getSubjectList
+                ]}
+                childrenField="instruments"
+                checkStrategy="child"
+                expandTrigger="click"
+                showPath={false}
+                v-model:value={state.searchForm.instrumentId}
+                onUpdate:value={(val: any, option: any, pathValues: any) => {
+                  console.log(val, option, pathValues);
+                }}
+              />
+            </NFormItem>
+            <NFormItem>
+              <NSpace justify="end">
+                <NButton type="primary" class="searchBtn" onClick={search}>
+                  搜索
+                </NButton>
+                <NButton
+                  type="primary"
+                  ghost
+                  class="resetBtn"
+                  onClick={onReset}>
+                  重置
+                </NButton>
+              </NSpace>
+            </NFormItem>
+          </NForm>
+        </div>
+        <NButton
+          class={styles.addBtn}
+          type="primary"
+          onClick={() => (state.showaddClass = true)}
+          v-slots={{
+            icon: () => (
+              <>
+                <NImage
+                  class={styles.addBtnIcon}
+                  previewDisabled
+                  src={add}></NImage>
+              </>
+            )
+          }}>
+          创建班级
+        </NButton>
+        <div class={styles.tableWrap}>
+          <NDataTable
+            v-slots={{
+              empty: () => <TheEmpty></TheEmpty>
+            }}
+            class={styles.classTable}
+            loading={state.loading}
+            columns={columns()}
+            data={state.tableList}></NDataTable>
+          <Pagination
+            v-model:page={state.pagination.page}
+            v-model:pageSize={state.pagination.rows}
+            v-model:pageTotal={state.pagination.pageTotal}
+            onList={getList}
+            sync
+          />
+        </div>
+        <NModal
+          v-model:show={state.studentVisible}
+          preset="card"
+          class={['modalTitle background', styles.studentVisible]}
+          title={'学生调整'}>
+          <RestStudentBox
+            activeRow={state.activeRow}
+            onClose={() => (state.studentVisible = false)}
+            onGetList={() => getList()}></RestStudentBox>
+        </NModal>
+        <NModal
+          v-model:show={state.showaddClass}
+          style={{ width: '500px' }}
+          display-directive="if"
+          preset="card"
+          class={['modalTitle background']}
+          title={'创建班级'}>
+          <CreateClass
+            gradeYearList={state.popSelectYearList}
+            gradeNumList={state.gradeNumList}
+            classArray={classArray}
+            onGetList={() => getList()}
+            onClose={() => (state.showaddClass = false)}
+          />
+        </NModal>
+        <NModal
+          v-model:show={state.showResetClass}
+          style={{ width: '500px' }}
+          display-directive="if"
+          preset="card"
+          class={['modalTitle background']}
+          title={'修改乐器'}>
+          <ResetSubject
+            activeRow={state.activeRow}
+            onGetList={() => getList()}
+            onClose={() => (state.showResetClass = false)}
+          />
+        </NModal>
+
+        <NModal
+          v-model:show={state.showSubjectClass}
+          style={{ width: '500px' }}
+          preset="card"
+          class={['modalTitle background']}
+          title={'修改乐器'}>
+          {state.showSubjectClass ? (
+            <UpdateSubject
+              activeRow={state.activeRow}
+              onGetList={() => getList()}
+              onConfirm={(item: any) => {
+                //
+                router.push({
+                  path: '/prepare-lessons',
+                  query: {
+                    ...item
+                  }
+                });
+              }}
+              onClose={() => (state.showSubjectClass = false)}
+            />
+          ) : null}
+        </NModal>
+
+        {/* 上课弹窗 */}
+        <PreviewWindow
+          v-model:show={state.previewModal}
+          type="attend"
+          params={state.previewParams}
+        />
+
+        <NModal
+          v-model:show={state.removeVisiable}
+          preset="card"
+          class={['modalTitle', styles.removeVisiable]}
+          title={'删除班级'}>
+          <div class={styles.studentRemove}>
+            <p>
+              确定要删除班级么?
+              <span>删除班级信息将会清空</span>。
+            </p>
+
+            <NSpace class={styles.btnGroup} justify="center">
+              <NButton round type="primary" onClick={removeClass}>
+                确定
+              </NButton>
+              <NButton round onClick={() => (state.removeVisiable = false)}>
+                取消
+              </NButton>
+            </NSpace>
+          </div>
+        </NModal>
+
+        <NModal
+          v-model:show={state.groupVisiable}
+          preset="card"
+          class={['modalTitle', styles.removeVisiable]}
+          title={'创建群聊'}>
+          <div class={styles.studentRemove}>
+            <p style={{ textAlign: 'center' }}>是否创建班级群聊</p>
+
+            <NSpace class={styles.btnGroup} justify="center">
+              <NButton
+                round
+                type="primary"
+                onClick={submitGroup}
+                loading={state.groupBtnLoading}
+                disabled={state.groupBtnLoading}>
+                确定
+              </NButton>
+              <NButton round onClick={() => (state.groupVisiable = false)}>
+                取消
+              </NButton>
+            </NSpace>
+          </div>
+        </NModal>
+        {showGuide.value ? <ClassGuide></ClassGuide> : null}
+
+        {state.addStudentVisible ? (
+          <div
+            v-model:show={state.addStudentVisible}
+            class={['n-modal-mask', styles.popBox]}>
+            <AddStudentModel
+              activeRow={state.activeRow}
+              onClose={() => {
+                state.addStudentVisible = false;
+              }}></AddStudentModel>
+          </div>
+        ) : null}
+      </div>
+    );
+  }
+});

+ 421 - 421
src/views/prepare-lessons/components/directory-main/index.tsx

@@ -1,421 +1,421 @@
-import { computed, defineComponent, onMounted, reactive, ref } from 'vue';
-import styles from './index.module.less';
-import { NIcon, NSpin, NScrollbar, NModal, NImage } from 'naive-ui';
-import {
-  lessonCoursewareDetail,
-  lessonCoursewarePage,
-  tagUseCourseware
-} from '../../api';
-import SelectLessonware from './select-lessonware';
-import TheEmpty from '/src/components/TheEmpty';
-import { usePrepareStore } from '/src/store/modules/prepareLessons';
-import { useUserStore } from '/src/store/modules/users';
-import { useRoute } from 'vue-router';
-import { eventGlobal } from '/src/utils';
-import TheNoticeBar from '/src/components/TheNoticeBar';
-import { getSubjectList2 } from '/src/api/user';
-
-export default defineComponent({
-  name: 'directory-main',
-  setup() {
-    const route = useRoute();
-    const prepareStore = usePrepareStore();
-    const userStore = useUserStore();
-    const show = ref(true);
-    const forms = reactive({
-      lastUseCoursewareId: route.query.lastUseCoursewareId
-        ? route.query.lastUseCoursewareId + ''
-        : null, // 专辑编号
-      unit: route.query.unit ? route.query.unit + '' : null, // 声部
-      showSelectBookStatus: false,
-      coursewareStatus: false
-    });
-
-    const getLessonCourseware = async () => {
-      try {
-        const { data } = await lessonCoursewarePage({
-          page: 1,
-          rows: 99,
-          type: 'COURSEWARE',
-          enableFlag: 1
-        });
-        const result = data.rows || [];
-        if (result.length > 0) {
-          // 判断是否有默认数据
-          const selectItem = result.find(
-            (item: any) =>
-              item.id ===
-              (forms.lastUseCoursewareId ||
-                userStore.getUserInfo?.lastUseCoursewareId)
-          );
-          let id: any = null;
-          let subjectIds: any = null;
-          if (selectItem) {
-            prepareStore.setBaseCourseware(selectItem);
-            id = selectItem.id;
-            subjectIds = selectItem.subjectIds;
-          } else {
-            prepareStore.setBaseCourseware(result[0]);
-            id = result[0]?.id;
-            subjectIds = result[0].subjectIds;
-          }
-          setLastUseCoursewareId(id);
-
-          if (subjectIds) {
-            const { data } = await getSubjectList2({ subjectIds });
-            prepareStore.setInstrumentList(data);
-          }
-        }
-
-        forms.showSelectBookStatus = true;
-      } catch {
-        //
-      }
-    };
-
-    const getLessonCoursewareDetail = async () => {
-      try {
-        const baseCourseware: any = prepareStore.getBaseCourseware;
-        if (!baseCourseware.id) return;
-        const { data } = await lessonCoursewareDetail({
-          id: baseCourseware.id
-        });
-        const tempList: any = data.lessonList || [];
-        const defaultUnitIds = formatParentId(forms.unit, tempList);
-        tempList.forEach((item: any, index: number) => {
-          item.selected = false;
-          // 处理从备课页面带过来的参数
-          if (defaultUnitIds.length > 1) {
-            if (item.id === defaultUnitIds[0]) {
-              item.selected = true;
-              item.knowledgeList.forEach((know: any) => {
-                if (know.id === defaultUnitIds[1]) {
-                  prepareStore.setSelectKey(know?.id);
-                  prepareStore.setLessonCoursewareId(know?.lessonCoursewareId);
-                  prepareStore.setLessonCoursewareDetailId(
-                    know?.lessonCoursewareDetailId
-                  );
-                }
-              });
-            }
-          } else {
-            if (index === 0) {
-              item.selected = true;
-              const temp = item['knowledgeList'][0];
-              prepareStore.setSelectKey(temp?.id);
-              prepareStore.setLessonCoursewareId(temp?.lessonCoursewareId);
-              prepareStore.setLessonCoursewareDetailId(
-                temp?.lessonCoursewareDetailId
-              );
-            }
-          }
-        });
-        prepareStore.setTreeList(tempList);
-      } catch {
-        //
-      }
-    };
-
-    const formatParentId = (id: any, list: any, ids = [] as any) => {
-      for (const item of list) {
-        if (item.knowledgeList && item.knowledgeList.length > 0) {
-          const cIds: any = formatParentId(id, item.knowledgeList, [
-            ...ids,
-            item.id
-          ]);
-          if (cIds.includes(id)) {
-            return cIds;
-          }
-        }
-        if (item.id === id) {
-          return [...ids, id];
-        }
-      }
-      return ids;
-    };
-
-    const setLastUseCoursewareId = async (id: any) => {
-      try {
-        await tagUseCourseware({ coursewareId: id });
-        userStore.getInfo();
-      } catch {
-        //
-      }
-    };
-
-    const clickDetail = (child: any) => {
-      prepareStore.setSelectKey(child.id);
-      prepareStore.setLessonCoursewareId(child.lessonCoursewareId);
-      prepareStore.setLessonCoursewareDetailId(child.lessonCoursewareDetailId);
-    };
-
-    const onChangeClass = async (item: any) => {
-      show.value = true;
-      forms.lastUseCoursewareId = item.lastUseCoursewareId;
-      forms.unit = item.unit;
-      await getLessonCourseware();
-      await getLessonCoursewareDetail();
-      show.value = false;
-    };
-
-    const changeCourseware = async (item: any) => {
-      prepareStore.setBaseCourseware(item);
-      // prepareStore.setSubjectList(item.subjectList);
-
-      if (item.subjectIds) {
-        const { data } = await getSubjectList2({
-          subjectIds: item.subjectIds
-        });
-        prepareStore.setInstrumentList(data);
-
-        let status = false;
-        let tempInstrumentId: any = null;
-        data.forEach((item: any, index: number) => {
-          if (Array.isArray(item.instruments)) {
-            item.instruments.forEach((child: any, j: number) => {
-              if (child.id === prepareStore.getInstrumentId) {
-                status = true;
-              }
-              if (index === 0 && j === 0) {
-                tempInstrumentId = child.id;
-              }
-            });
-          }
-        });
-        // 判断教材里面是否有当前选择的声部,如果没有则默认选择第一个
-        if (status) {
-          const instrumentId = tempInstrumentId;
-          sessionStorage.removeItem('prepareLessonCourseWareSubjectIsNull');
-          prepareStore.setInstrumentId(instrumentId);
-        }
-      }
-
-      getLessonCoursewareDetail();
-      setLastUseCoursewareId(item.id);
-    };
-
-    const formatInstrumentNames = computed(() => {
-      const names = prepareStore.getBaseCourseware.instrumentNames;
-      if (!names) {
-        return '';
-      }
-      return names.split(',').join('、');
-    });
-
-    onMounted(async () => {
-      show.value = true;
-      await getLessonCourseware();
-      await getLessonCoursewareDetail();
-      show.value = false;
-
-      // 切换班级时触发
-      eventGlobal.on('onChangeClass', async (item: any) => {
-        onChangeClass(item);
-      });
-    });
-    return () => (
-      <div class={styles.directoryList}>
-        {forms.showSelectBookStatus &&
-          (prepareStore.getBaseCourseware.id ? (
-            <div id="lessons-0" class={styles['select-directory-info']}>
-              <div
-                class={styles.itemImg}
-                onClick={() => (forms.coursewareStatus = true)}>
-                <NImage
-                  objectFit="cover"
-                  src={prepareStore.getBaseCourseware.coverImg}
-                  lazy
-                  previewDisabled={true}
-                  onLoad={e => {
-                    (e.target as any).dataset.loaded = 'true';
-                  }}
-                />
-              </div>
-              <div class={styles.itemContent}>
-                <h2>
-                  <TheNoticeBar text={prepareStore.getBaseCourseware.name} />
-                </h2>
-                <div class={styles.subjects}>
-                  <TheNoticeBar
-                    text={formatInstrumentNames.value}
-                    time={formatInstrumentNames.value.length > 15 ? 10 : 5}
-                  />
-                </div>
-                <div
-                  class={styles.changeDir}
-                  onClick={() => (forms.coursewareStatus = true)}>
-                  <svg
-                    width="11px"
-                    height="10px"
-                    viewBox="0 0 11 10"
-                    version="1.1"
-                    xmlns="http://www.w3.org/2000/svg">
-                    <title>切片</title>
-                    <g
-                      stroke="none"
-                      stroke-width="1"
-                      fill="none"
-                      fill-rule="evenodd">
-                      <g
-                        transform="translate(-279.000000, -210.000000)"
-                        fill="#0378EC"
-                        fill-rule="nonzero">
-                        <g transform="translate(132.000000, 96.000000)">
-                          <g transform="translate(32.000000, 24.000000)">
-                            <g transform="translate(103.000000, 10.000000)">
-                              <g transform="translate(0.000000, 71.000000)">
-                                <g transform="translate(12.000000, 9.000000)">
-                                  <path d="M10.4116565,3.89985699 C10.6551462,3.89985699 10.8747497,3.75140792 10.9680437,3.52360884 C11.0613377,3.29606287 11.0096883,3.03384082 10.8376072,2.85944797 L8.08018279,0.0692888872 C7.98888976,-0.0230962957 7.8410701,-0.0230962957 7.74977708,0.0692888872 L7.22840639,0.59689687 C7.13711336,0.689282053 7.13711336,0.838996672 7.22840639,0.931255299 L8.95772133,2.68113191 L0.230858792,2.68113191 C0.103423738,2.68113191 0,2.78566638 0,2.91475252 L0,3.66636293 C0,3.79532253 0.10329868,3.89998355 0.230858792,3.89998355 L10.4116565,3.89998355 L10.4116565,3.89985699 Z M10.877501,6.10001645 L0.699579677,6.10001645 C0.456089932,6.10001645 0.236486444,6.24846552 0.143192479,6.4762646 C0.0498985147,6.70381057 0.101547854,6.96603263 0.273628948,7.14042548 L3.03105338,9.93071111 C3.12234641,10.0230963 3.27016607,10.0230963 3.36145909,9.93071111 L3.88282978,9.40310313 C3.97412281,9.31071795 3.97412281,9.16100333 3.88282978,9.0687447 L2.15351484,7.31874154 L10.877501,7.31874154 C11.0065618,7.31874154 11.1111111,7.21281496 11.1111111,7.08233671 L11.1111111,6.33654783 C11.1111111,6.20594302 11.0065618,6.10001645 10.877501,6.10001645 Z"></path>
-                                </g>
-                              </g>
-                            </g>
-                          </g>
-                        </g>
-                      </g>
-                    </g>
-                  </svg>
-                  <span>切换教材</span>
-                </div>
-              </div>
-            </div>
-          ) : (
-            <div
-              id="lessons-0"
-              class={styles['select-directory']}
-              onClick={() => (forms.coursewareStatus = true)}>
-              <span
-                class={['cr-ellipsis']}
-                title={prepareStore.getBaseCourseware.name}>
-                {prepareStore.getBaseCourseware.name || '请选择教材'}
-              </span>
-              <NIcon class={styles.iconArrow}>
-                <svg
-                  width="11px"
-                  height="15px"
-                  viewBox="0 0 11 15"
-                  version="1.1"
-                  xmlns="http://www.w3.org/2000/svg">
-                  <g
-                    stroke="none"
-                    stroke-width="1"
-                    fill="none"
-                    fill-rule="evenodd"
-                    opacity="0.699999988">
-                    <g
-                      transform="translate(-445.000000, -137.000000)"
-                      fill="#131415">
-                      <g transform="translate(152.000000, 120.000000)">
-                        <path
-                          d="M299.326227,20.2118001 L304.934089,28.4366632 C305.245211,28.8929759 305.127511,29.515105 304.671198,29.8262273 C304.505147,29.9394437 304.308836,30 304.107861,30 L292.892139,30 C292.339854,30 291.892139,29.5522847 291.892139,29 C291.892139,28.7990254 291.952695,28.6027139 292.065911,28.4366632 L297.673773,20.2118001 C297.984895,19.7554873 298.607024,19.6377872 299.063337,19.9489096 C299.16663,20.0193364 299.255801,20.1085074 299.326227,20.2118001 Z"
-                          id="三角形"
-                          transform="translate(298.500000, 24.500000) rotate(-270.000000) translate(-298.500000, -24.500000) "></path>
-                      </g>
-                    </g>
-                  </g>
-                </svg>
-              </NIcon>
-            </div>
-          ))}
-
-        <NScrollbar class={styles.scrollBar}>
-          <NSpin show={show.value}>
-            <div
-              class={[
-                styles.listSection,
-                !show.value && prepareStore.getTreeList.length <= 0
-                  ? styles.emptySection
-                  : ''
-              ]}>
-              {prepareStore.getTreeList.map((item: any, index: number) => (
-                <div class={styles.treeParent} key={'parent' + index}>
-                  <div
-                    class={[styles.treeItem, styles.parentItem]}
-                    onClick={() => {
-                      prepareStore.getTreeList.forEach((child: any) => {
-                        if (item.id !== child.id) {
-                          child.selected = false;
-                        }
-                      });
-                      item.selected = item.selected ? false : true;
-                    }}>
-                    {item.knowledgeList && item.knowledgeList.length > 0 && (
-                      <span
-                        class={[
-                          styles.arrow,
-                          item.selected ? styles.arrowSelect : ''
-                        ]}></span>
-                    )}
-                    <p
-                      class={[
-                        styles.title,
-                        item.selected ? styles.titleSelect : ''
-                      ]}>
-                      <span
-                        class={[
-                          styles.dir,
-                          item.selected ? styles.dirSelect : ''
-                        ]}></span>
-                      {item.name}
-                    </p>
-                  </div>
-
-                  {item.selected &&
-                    item.knowledgeList &&
-                    item.knowledgeList.map((child: any, j: number) => (
-                      <div
-                        key={'child' + j}
-                        class={[
-                          styles.treeItem,
-                          styles.childItem,
-                          styles.animation,
-                          prepareStore.getSelectKey === child.id
-                            ? styles.childSelect
-                            : ''
-                        ]}
-                        onClick={() => {
-                          if (prepareStore.getIsEditResource) {
-                            eventGlobal.emit('pageBeforeLeave', () =>
-                              clickDetail(child)
-                            );
-                          } else {
-                            clickDetail(child);
-                          }
-                        }}>
-                        <span class={styles.childArrow}></span>
-                        <p class={styles.title}>{child.name}</p>
-                      </div>
-                    ))}
-                </div>
-              ))}
-            </div>
-            {!show.value && prepareStore.getTreeList.length <= 0 && (
-              <TheEmpty />
-            )}
-          </NSpin>
-        </NScrollbar>
-
-        {/* 选择教材 */}
-        <NModal
-          v-model:show={forms.coursewareStatus}
-          preset="card"
-          showIcon={false}
-          class={['modalTitle background', styles.coursewareModal]}
-          title={'切换教材'}
-          blockScroll={false}>
-          <SelectLessonware
-            onClose={() => (forms.coursewareStatus = false)}
-            onConfirm={(item: any) => {
-              if (prepareStore.getIsEditResource) {
-                eventGlobal.emit('pageBeforeLeave', () =>
-                  changeCourseware(item)
-                );
-              } else {
-                changeCourseware(item);
-              }
-            }}
-          />
-        </NModal>
-      </div>
-    );
-  }
-});
+import { computed, defineComponent, onMounted, reactive, ref } from 'vue';
+import styles from './index.module.less';
+import { NIcon, NSpin, NScrollbar, NModal, NImage } from 'naive-ui';
+import {
+  lessonCoursewareDetail,
+  lessonCoursewarePage,
+  tagUseCourseware
+} from '../../api';
+import SelectLessonware from './select-lessonware';
+import TheEmpty from '/src/components/TheEmpty';
+import { usePrepareStore } from '/src/store/modules/prepareLessons';
+import { useUserStore } from '/src/store/modules/users';
+import { useRoute } from 'vue-router';
+import { eventGlobal } from '/src/utils';
+import TheNoticeBar from '/src/components/TheNoticeBar';
+import { getSubjectList2 } from '/src/api/user';
+
+export default defineComponent({
+  name: 'directory-main',
+  setup() {
+    const route = useRoute();
+    const prepareStore = usePrepareStore();
+    const userStore = useUserStore();
+    const show = ref(true);
+    const forms = reactive({
+      lastUseCoursewareId: route.query.lastUseCoursewareId
+        ? route.query.lastUseCoursewareId + ''
+        : null, // 专辑编号
+      unit: route.query.unit ? route.query.unit + '' : null, // 声部
+      showSelectBookStatus: false,
+      coursewareStatus: false
+    });
+
+    const getLessonCourseware = async () => {
+      try {
+        const { data } = await lessonCoursewarePage({
+          page: 1,
+          rows: 99,
+          type: 'COURSEWARE',
+          enableFlag: 1
+        });
+        const result = data.rows || [];
+        if (result.length > 0) {
+          // 判断是否有默认数据
+          const selectItem = result.find(
+            (item: any) =>
+              item.id ===
+              (forms.lastUseCoursewareId ||
+                userStore.getUserInfo?.lastUseCoursewareId)
+          );
+          let id: any = null;
+          let instrumentIds: any = null;
+          if (selectItem) {
+            prepareStore.setBaseCourseware(selectItem);
+            id = selectItem.id;
+            instrumentIds = selectItem.instrumentIds;
+          } else {
+            prepareStore.setBaseCourseware(result[0]);
+            id = result[0]?.id;
+            instrumentIds = result[0].instrumentIds;
+          }
+          setLastUseCoursewareId(id);
+
+          if (instrumentIds) {
+            const { data } = await getSubjectList2({ instrumentIds });
+            prepareStore.setInstrumentList(data);
+          }
+        }
+
+        forms.showSelectBookStatus = true;
+      } catch {
+        //
+      }
+    };
+
+    const getLessonCoursewareDetail = async () => {
+      try {
+        const baseCourseware: any = prepareStore.getBaseCourseware;
+        if (!baseCourseware.id) return;
+        const { data } = await lessonCoursewareDetail({
+          id: baseCourseware.id
+        });
+        const tempList: any = data.lessonList || [];
+        const defaultUnitIds = formatParentId(forms.unit, tempList);
+        tempList.forEach((item: any, index: number) => {
+          item.selected = false;
+          // 处理从备课页面带过来的参数
+          if (defaultUnitIds.length > 1) {
+            if (item.id === defaultUnitIds[0]) {
+              item.selected = true;
+              item.knowledgeList.forEach((know: any) => {
+                if (know.id === defaultUnitIds[1]) {
+                  prepareStore.setSelectKey(know?.id);
+                  prepareStore.setLessonCoursewareId(know?.lessonCoursewareId);
+                  prepareStore.setLessonCoursewareDetailId(
+                    know?.lessonCoursewareDetailId
+                  );
+                }
+              });
+            }
+          } else {
+            if (index === 0) {
+              item.selected = true;
+              const temp = item['knowledgeList'][0];
+              prepareStore.setSelectKey(temp?.id);
+              prepareStore.setLessonCoursewareId(temp?.lessonCoursewareId);
+              prepareStore.setLessonCoursewareDetailId(
+                temp?.lessonCoursewareDetailId
+              );
+            }
+          }
+        });
+        prepareStore.setTreeList(tempList);
+      } catch {
+        //
+      }
+    };
+
+    const formatParentId = (id: any, list: any, ids = [] as any) => {
+      for (const item of list) {
+        if (item.knowledgeList && item.knowledgeList.length > 0) {
+          const cIds: any = formatParentId(id, item.knowledgeList, [
+            ...ids,
+            item.id
+          ]);
+          if (cIds.includes(id)) {
+            return cIds;
+          }
+        }
+        if (item.id === id) {
+          return [...ids, id];
+        }
+      }
+      return ids;
+    };
+
+    const setLastUseCoursewareId = async (id: any) => {
+      try {
+        await tagUseCourseware({ coursewareId: id });
+        userStore.getInfo();
+      } catch {
+        //
+      }
+    };
+
+    const clickDetail = (child: any) => {
+      prepareStore.setSelectKey(child.id);
+      prepareStore.setLessonCoursewareId(child.lessonCoursewareId);
+      prepareStore.setLessonCoursewareDetailId(child.lessonCoursewareDetailId);
+    };
+
+    const onChangeClass = async (item: any) => {
+      show.value = true;
+      forms.lastUseCoursewareId = item.lastUseCoursewareId;
+      forms.unit = item.unit;
+      await getLessonCourseware();
+      await getLessonCoursewareDetail();
+      show.value = false;
+    };
+
+    const changeCourseware = async (item: any) => {
+      prepareStore.setBaseCourseware(item);
+      // prepareStore.setSubjectList(item.subjectList);
+
+      if (item.instrumentIds) {
+        const { data } = await getSubjectList2({
+          instrumentIds: item.instrumentIds
+        });
+        prepareStore.setInstrumentList(data);
+
+        let status = false;
+        let tempInstrumentId: any = null;
+        data.forEach((item: any, index: number) => {
+          if (Array.isArray(item.instruments)) {
+            item.instruments.forEach((child: any, j: number) => {
+              if (child.id === prepareStore.getInstrumentId) {
+                status = true;
+              }
+              if (index === 0 && j === 0) {
+                tempInstrumentId = child.id;
+              }
+            });
+          }
+        });
+        // 判断教材里面是否有当前选择的声部,如果没有则默认选择第一个
+        if (status) {
+          const instrumentId = tempInstrumentId;
+          sessionStorage.removeItem('prepareLessonCourseWareSubjectIsNull');
+          prepareStore.setInstrumentId(instrumentId);
+        }
+      }
+
+      getLessonCoursewareDetail();
+      setLastUseCoursewareId(item.id);
+    };
+
+    const formatInstrumentNames = computed(() => {
+      const names = prepareStore.getBaseCourseware.instrumentNames;
+      if (!names) {
+        return '';
+      }
+      return names.split(',').join('、');
+    });
+
+    onMounted(async () => {
+      show.value = true;
+      await getLessonCourseware();
+      await getLessonCoursewareDetail();
+      show.value = false;
+
+      // 切换班级时触发
+      eventGlobal.on('onChangeClass', async (item: any) => {
+        onChangeClass(item);
+      });
+    });
+    return () => (
+      <div class={styles.directoryList}>
+        {forms.showSelectBookStatus &&
+          (prepareStore.getBaseCourseware.id ? (
+            <div id="lessons-0" class={styles['select-directory-info']}>
+              <div
+                class={styles.itemImg}
+                onClick={() => (forms.coursewareStatus = true)}>
+                <NImage
+                  objectFit="cover"
+                  src={prepareStore.getBaseCourseware.coverImg}
+                  lazy
+                  previewDisabled={true}
+                  onLoad={e => {
+                    (e.target as any).dataset.loaded = 'true';
+                  }}
+                />
+              </div>
+              <div class={styles.itemContent}>
+                <h2>
+                  <TheNoticeBar text={prepareStore.getBaseCourseware.name} />
+                </h2>
+                <div class={styles.subjects}>
+                  <TheNoticeBar
+                    text={formatInstrumentNames.value}
+                    time={formatInstrumentNames.value.length > 15 ? 10 : 5}
+                  />
+                </div>
+                <div
+                  class={styles.changeDir}
+                  onClick={() => (forms.coursewareStatus = true)}>
+                  <svg
+                    width="11px"
+                    height="10px"
+                    viewBox="0 0 11 10"
+                    version="1.1"
+                    xmlns="http://www.w3.org/2000/svg">
+                    <title>切片</title>
+                    <g
+                      stroke="none"
+                      stroke-width="1"
+                      fill="none"
+                      fill-rule="evenodd">
+                      <g
+                        transform="translate(-279.000000, -210.000000)"
+                        fill="#0378EC"
+                        fill-rule="nonzero">
+                        <g transform="translate(132.000000, 96.000000)">
+                          <g transform="translate(32.000000, 24.000000)">
+                            <g transform="translate(103.000000, 10.000000)">
+                              <g transform="translate(0.000000, 71.000000)">
+                                <g transform="translate(12.000000, 9.000000)">
+                                  <path d="M10.4116565,3.89985699 C10.6551462,3.89985699 10.8747497,3.75140792 10.9680437,3.52360884 C11.0613377,3.29606287 11.0096883,3.03384082 10.8376072,2.85944797 L8.08018279,0.0692888872 C7.98888976,-0.0230962957 7.8410701,-0.0230962957 7.74977708,0.0692888872 L7.22840639,0.59689687 C7.13711336,0.689282053 7.13711336,0.838996672 7.22840639,0.931255299 L8.95772133,2.68113191 L0.230858792,2.68113191 C0.103423738,2.68113191 0,2.78566638 0,2.91475252 L0,3.66636293 C0,3.79532253 0.10329868,3.89998355 0.230858792,3.89998355 L10.4116565,3.89998355 L10.4116565,3.89985699 Z M10.877501,6.10001645 L0.699579677,6.10001645 C0.456089932,6.10001645 0.236486444,6.24846552 0.143192479,6.4762646 C0.0498985147,6.70381057 0.101547854,6.96603263 0.273628948,7.14042548 L3.03105338,9.93071111 C3.12234641,10.0230963 3.27016607,10.0230963 3.36145909,9.93071111 L3.88282978,9.40310313 C3.97412281,9.31071795 3.97412281,9.16100333 3.88282978,9.0687447 L2.15351484,7.31874154 L10.877501,7.31874154 C11.0065618,7.31874154 11.1111111,7.21281496 11.1111111,7.08233671 L11.1111111,6.33654783 C11.1111111,6.20594302 11.0065618,6.10001645 10.877501,6.10001645 Z"></path>
+                                </g>
+                              </g>
+                            </g>
+                          </g>
+                        </g>
+                      </g>
+                    </g>
+                  </svg>
+                  <span>切换教材</span>
+                </div>
+              </div>
+            </div>
+          ) : (
+            <div
+              id="lessons-0"
+              class={styles['select-directory']}
+              onClick={() => (forms.coursewareStatus = true)}>
+              <span
+                class={['cr-ellipsis']}
+                title={prepareStore.getBaseCourseware.name}>
+                {prepareStore.getBaseCourseware.name || '请选择教材'}
+              </span>
+              <NIcon class={styles.iconArrow}>
+                <svg
+                  width="11px"
+                  height="15px"
+                  viewBox="0 0 11 15"
+                  version="1.1"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <g
+                    stroke="none"
+                    stroke-width="1"
+                    fill="none"
+                    fill-rule="evenodd"
+                    opacity="0.699999988">
+                    <g
+                      transform="translate(-445.000000, -137.000000)"
+                      fill="#131415">
+                      <g transform="translate(152.000000, 120.000000)">
+                        <path
+                          d="M299.326227,20.2118001 L304.934089,28.4366632 C305.245211,28.8929759 305.127511,29.515105 304.671198,29.8262273 C304.505147,29.9394437 304.308836,30 304.107861,30 L292.892139,30 C292.339854,30 291.892139,29.5522847 291.892139,29 C291.892139,28.7990254 291.952695,28.6027139 292.065911,28.4366632 L297.673773,20.2118001 C297.984895,19.7554873 298.607024,19.6377872 299.063337,19.9489096 C299.16663,20.0193364 299.255801,20.1085074 299.326227,20.2118001 Z"
+                          id="三角形"
+                          transform="translate(298.500000, 24.500000) rotate(-270.000000) translate(-298.500000, -24.500000) "></path>
+                      </g>
+                    </g>
+                  </g>
+                </svg>
+              </NIcon>
+            </div>
+          ))}
+
+        <NScrollbar class={styles.scrollBar}>
+          <NSpin show={show.value}>
+            <div
+              class={[
+                styles.listSection,
+                !show.value && prepareStore.getTreeList.length <= 0
+                  ? styles.emptySection
+                  : ''
+              ]}>
+              {prepareStore.getTreeList.map((item: any, index: number) => (
+                <div class={styles.treeParent} key={'parent' + index}>
+                  <div
+                    class={[styles.treeItem, styles.parentItem]}
+                    onClick={() => {
+                      prepareStore.getTreeList.forEach((child: any) => {
+                        if (item.id !== child.id) {
+                          child.selected = false;
+                        }
+                      });
+                      item.selected = item.selected ? false : true;
+                    }}>
+                    {item.knowledgeList && item.knowledgeList.length > 0 && (
+                      <span
+                        class={[
+                          styles.arrow,
+                          item.selected ? styles.arrowSelect : ''
+                        ]}></span>
+                    )}
+                    <p
+                      class={[
+                        styles.title,
+                        item.selected ? styles.titleSelect : ''
+                      ]}>
+                      <span
+                        class={[
+                          styles.dir,
+                          item.selected ? styles.dirSelect : ''
+                        ]}></span>
+                      {item.name}
+                    </p>
+                  </div>
+
+                  {item.selected &&
+                    item.knowledgeList &&
+                    item.knowledgeList.map((child: any, j: number) => (
+                      <div
+                        key={'child' + j}
+                        class={[
+                          styles.treeItem,
+                          styles.childItem,
+                          styles.animation,
+                          prepareStore.getSelectKey === child.id
+                            ? styles.childSelect
+                            : ''
+                        ]}
+                        onClick={() => {
+                          if (prepareStore.getIsEditResource) {
+                            eventGlobal.emit('pageBeforeLeave', () =>
+                              clickDetail(child)
+                            );
+                          } else {
+                            clickDetail(child);
+                          }
+                        }}>
+                        <span class={styles.childArrow}></span>
+                        <p class={styles.title}>{child.name}</p>
+                      </div>
+                    ))}
+                </div>
+              ))}
+            </div>
+            {!show.value && prepareStore.getTreeList.length <= 0 && (
+              <TheEmpty />
+            )}
+          </NSpin>
+        </NScrollbar>
+
+        {/* 选择教材 */}
+        <NModal
+          v-model:show={forms.coursewareStatus}
+          preset="card"
+          showIcon={false}
+          class={['modalTitle background', styles.coursewareModal]}
+          title={'切换教材'}
+          blockScroll={false}>
+          <SelectLessonware
+            onClose={() => (forms.coursewareStatus = false)}
+            onConfirm={(item: any) => {
+              if (prepareStore.getIsEditResource) {
+                eventGlobal.emit('pageBeforeLeave', () =>
+                  changeCourseware(item)
+                );
+              } else {
+                changeCourseware(item);
+              }
+            }}
+          />
+        </NModal>
+      </div>
+    );
+  }
+});

+ 431 - 431
src/views/prepare-lessons/components/lesson-main/courseware-presets/index.module.less

@@ -1,432 +1,432 @@
-.coursewarePresetsContainer {
-  // padding-bottom: 20px;
-  height: 100%;
-  display: flex;
-  // position: relative;
-  // overflow: hidden;
-
-  &.rightLineShow {
-    .presetsRight {
-      transition: all .1s ease;
-      opacity: 1;
-      position: relative;
-      transform: none;
-    }
-
-    // .list {
-    //   .itemWrap {
-    //     // width: calc(100% / 3);
-    //     width: 336px;
-    //   }
-    // }
-  }
-
-  :global {
-    .n-base-selection {
-      --n-height: max(36px, 32Px) !important;
-      width: 220px;
-      font-size: max(13px, 12Px);
-      border-radius: 7px !important;
-    }
-
-    .n-base-selection-input__content {
-      font-size: max(15px, 13Px);
-    }
-
-    .n-tabs-tab-pad {
-      width: 33px !important;
-    }
-
-    .n-tabs-tab.n-tabs-tab--disabled {
-      color: #8B8D98 !important;
-    }
-
-    .n-tabs-nav {
-      padding-top: 20px;
-      padding-bottom: 10px;
-      padding-left: 30px;
-      padding-right: 30px;
-    }
-  }
-
-  .presetsLeft {
-    flex: 1;
-    transition: all .1s ease;
-  }
-
-  .presetsRight {
-    position: relative;
-    background: #FFFFFF;
-    box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.1);
-    border-radius: 0px 17px 17px 0px;
-    flex: 0 0 340px;
-
-    transition: all .1s ease;
-    position: absolute;
-    right: 0;
-    top: 0;
-    bottom: 0;
-    transform: translateX(100%);
-
-
-    .presetsArrar {
-      position: absolute;
-      left: -23px;
-      top: 50%;
-      margin-top: -30px;
-      width: 23px;
-      height: 50px;
-      line-height: 50px;
-      cursor: pointer;
-      background-color: #F5F6FA;
-      border-radius: 10px 0 0 10px;
-      color: #ABAEB0;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-
-      svg {
-        transform: rotate(180deg);
-      }
-
-      &:hover {
-        color: #198CFE;
-      }
-
-      &.presetsArrarActive {
-        svg {
-          transform: rotate(0deg);
-        }
-      }
-    }
-  }
-}
-
-.openLoading {
-  min-height: 200px;
-}
-
-.coursewarePresets {
-  max-height: calc(var(--window-page-lesson-height) - 100px);
-  min-height: calc(var(--window-page-lesson-height) - 100px);
-  // padding: 0 20px 0px;
-}
-
-.btnSubjectList {
-  :global {
-    .n-base-selection-input {
-      padding-left: 8px;
-    }
-  }
-}
-
-.addBtnIcon {
-  width: 18px !important;
-  height: 18px !important;
-  margin-right: 8px;
-}
-
-.addBtn {
-  // height: max(36px, 32Px) !important;
-  background: linear-gradient(312deg, #1B7AF8 0%, #3CBBFF 100%) !important;
-  border-radius: 7Px !important;
-  padding: 0 16Px !important;
-  border-radius: 8px;
-  height: max(38px, 32Px);
-  font-size: max(18px, 13Px) !important;
-  font-weight: 600 !important;
-  position: relative;
-  z-index: 9;
-
-  &::after {
-    content: '';
-    position: absolute;
-    left: 10%;
-    bottom: -1px;
-    display: inline-block;
-    width: 80%;
-    height: 8px;
-    background: linear-gradient(136deg, #31ABFF 0%, #1A7BF8 100%);
-    opacity: 0.6;
-    filter: blur(7px);
-  }
-
-  &:hover {
-    // &::after {
-    background: linear-gradient(135deg, #62C7FF 0%, #4995FA 100%) !important;
-    // }
-  }
-}
-
-
-.title {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  font-weight: 600;
-  font-size: max(17px, 14Px);
-  color: #000000;
-  line-height: 23px;
-  height: 23px;
-  text-align: left;
-  padding-bottom: 20px;
-  box-sizing: content-box;
-
-  .titleLeft {
-    display: flex;
-    align-items: center;
-  }
-
-  .icon {
-    display: inline-block;
-    width: 20px;
-    height: 20px;
-    margin-right: 3px;
-  }
-
-  .iconWork {
-    background: url('../../../images/icon-knowlage.png') no-repeat center center;
-    background-size: contain;
-  }
-
-  .iconCourseware {
-    background: url('../../../images/icon-courseware.png') no-repeat center center;
-    background-size: contain;
-  }
-
-  &.line {
-    margin-top: 25px;
-    border-top: 1px solid #F2F2F2;
-    padding-top: 35px;
-
-    .more {
-      display: flex;
-      align-items: center;
-      cursor: pointer;
-      padding-left: 10px;
-      font-weight: 400;
-      font-size: max(13px, 12Px);
-      color: #999999;
-
-      &:hover {
-        color: #1677FF;
-
-        .iconP {
-          background: url('../../../images/icon-arrow-p-active.png') no-repeat center;
-          background-size: contain;
-        }
-      }
-    }
-
-    .iconP {
-      width: 8px;
-      height: 11px;
-      display: inline-block;
-      background: url('../../../images/icon-arrow-p.png') no-repeat center;
-      background-size: contain;
-      margin-left: 4px;
-    }
-
-    .swipeControll {
-      height: 25px;
-
-      .leftIcon {
-        transform: rotate(180deg);
-      }
-
-      img {
-        cursor: pointer;
-        width: 25px;
-        height: 25px;
-      }
-
-      .disabled {
-        opacity: 0.4;
-        cursor: not-allowed;
-      }
-    }
-  }
-}
-
-.listLoading {}
-
-.list {
-  display: flex;
-  flex-flow: row wrap;
-  justify-content: flex-start;
-  padding: 10px 20px 12px;
-  // padding: 0 20px 0px;
-  gap: 10px 0;
-  margin: 0 -10px 0;
-  // height: 313px;
-
-
-  &.listEmpty {
-    min-height: calc(var(--window-page-lesson-height) - 100px);
-    align-items: center;
-  }
-
-  &.listSame {
-    margin-top: 0;
-    padding-top: 0;
-  }
-
-  .empty1 {
-    // padding: 10px 0;
-  }
-
-  .itemWrap {
-    // width: calc(100% / 4);
-    width: 336px;
-    // padding-bottom: calc(100% / 3 * 0.73333);
-    // position: relative;
-
-    .itemWrapBox {
-      //   position: absolute;
-      //   left: 0;
-      //   top: 0;
-      //   width: 100%;
-      //   height: 100%;
-      padding: 0 10px;
-    }
-  }
-
-}
-
-.itemWrapBox {
-  padding: 0 10px;
-}
-
-.attendClassModal1 {
-  width: 1360px;
-  border-radius: 16px;
-  overflow: hidden;
-}
-
-.removeVisiable1 {
-  width: 432px;
-
-  :global {
-    .n-card-header {
-      font-size: max(22px, 16Px);
-    }
-  }
-
-  .studentRemove {
-    padding: 20px 40px 0;
-
-    p {
-      font-size: max(18px, 14Px);
-      color: #777777;
-      line-height: 30px;
-
-      span {
-        color: #EA4132;
-      }
-    }
-  }
-
-  .btnGroupModal {
-    padding: 32px 0;
-
-    :global {
-      .n-button {
-        height: 47px;
-        min-width: 156px;
-      }
-    }
-  }
-}
-
-.attendClassModal {
-  width: 800px;
-  border-radius: 16px;
-  overflow: hidden;
-}
-
-.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);
-  }
-}
-
-.popSelect {
-  font-size: 16px;
-  width: 200px;
-  box-shadow: 0px 2 16px 0px rgba(0, 0, 0, 0.08);
-  border-radius: 11px;
-  --n-option-height: 34px;
-
-  :global {
-    .n-base-select-option__content {
-      width: 80% !important;
-    }
-  }
-}
-
-.textBtn {
-  // background: #fff;
-  // border-radius: 8Px;
-  // padding: 4Px 0;
-  // font-size: max(16px, 13Px);
-  // color: rgba(0, 0, 0, 0.6);
-  position: relative;
-  cursor: pointer;
-  display: flex;
-  align-items: center;
-  font-weight: 500;
-
-  .iconArrow {
-    display: inline-block;
-    margin-left: 8px;
-    width: 8px;
-    height: 5px;
-    background: url('@/views/prepare-lessons/images/icon-arrow-1.png') no-repeat center center / contain;
-    // transform: rotate(180deg);
-  }
-
-  &:hover,
-  &.textBtnActive {
-    // background: #D2ECFF;
-    font-weight: 500;
-    color: #131415;
-  }
-
-  &:hover {
-    color: #198CFE;
-
-    .iconArrow {
-      // transform: rotate(0deg);
-      background: url('@/views/prepare-lessons/images/icon-arrow-2.png') no-repeat center center / contain;
-    }
-  }
+.coursewarePresetsContainer {
+  // padding-bottom: 20px;
+  height: 100%;
+  display: flex;
+  // position: relative;
+  // overflow: hidden;
+
+  &.rightLineShow {
+    .presetsRight {
+      transition: all .1s ease;
+      opacity: 1;
+      position: relative;
+      transform: none;
+    }
+
+    // .list {
+    //   .itemWrap {
+    //     // width: calc(100% / 3);
+    //     width: 336px;
+    //   }
+    // }
+  }
+
+  :global {
+    .n-base-selection {
+      --n-height: max(36px, 32Px) !important;
+      width: 220px;
+      font-size: max(13px, 12Px);
+      border-radius: 7px !important;
+    }
+
+    .n-base-selection-input__content {
+      font-size: max(15px, 13Px);
+    }
+
+    .n-tabs-tab-pad {
+      width: 33px !important;
+    }
+
+    .n-tabs-tab.n-tabs-tab--disabled {
+      color: #8B8D98 !important;
+    }
+
+    .n-tabs-nav {
+      padding-top: 20px;
+      padding-bottom: 10px;
+      padding-left: 30px;
+      padding-right: 30px;
+    }
+  }
+
+  .presetsLeft {
+    flex: 1;
+    transition: all .1s ease;
+  }
+
+  .presetsRight {
+    position: relative;
+    background: #FFFFFF;
+    box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.1);
+    border-radius: 0px 17px 17px 0px;
+    flex: 0 0 340px;
+
+    transition: all .1s ease;
+    position: absolute;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    transform: translateX(100%);
+
+
+    .presetsArrar {
+      position: absolute;
+      left: -23px;
+      top: 50%;
+      margin-top: -30px;
+      width: 23px;
+      height: 50px;
+      line-height: 50px;
+      cursor: pointer;
+      background-color: #F5F6FA;
+      border-radius: 10px 0 0 10px;
+      color: #ABAEB0;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+
+      svg {
+        transform: rotate(180deg);
+      }
+
+      &:hover {
+        color: #198CFE;
+      }
+
+      &.presetsArrarActive {
+        svg {
+          transform: rotate(0deg);
+        }
+      }
+    }
+  }
+}
+
+.openLoading {
+  min-height: 200px;
+}
+
+.coursewarePresets {
+  max-height: calc(var(--window-page-lesson-height) - 100px);
+  min-height: calc(var(--window-page-lesson-height) - 100px);
+  // padding: 0 20px 0px;
+}
+
+.btnSubjectList {
+  :global {
+    .n-base-selection-input {
+      padding-left: 8px;
+    }
+  }
+}
+
+.addBtnIcon {
+  width: 18px !important;
+  height: 18px !important;
+  margin-right: 8px;
+}
+
+.addBtn {
+  // height: max(36px, 32Px) !important;
+  background: linear-gradient(312deg, #1B7AF8 0%, #3CBBFF 100%) !important;
+  border-radius: 7Px !important;
+  padding: 0 16Px !important;
+  border-radius: 8px;
+  height: max(38px, 32Px);
+  font-size: max(18px, 13Px) !important;
+  font-weight: 600 !important;
+  position: relative;
+  z-index: 9;
+
+  &::after {
+    content: '';
+    position: absolute;
+    left: 10%;
+    bottom: -1px;
+    display: inline-block;
+    width: 80%;
+    height: 8px;
+    background: linear-gradient(136deg, #31ABFF 0%, #1A7BF8 100%);
+    opacity: 0.6;
+    filter: blur(7px);
+  }
+
+  &:hover {
+    // &::after {
+    background: linear-gradient(135deg, #62C7FF 0%, #4995FA 100%) !important;
+    // }
+  }
+}
+
+
+.title {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  font-weight: 600;
+  font-size: max(17px, 14Px);
+  color: #000000;
+  line-height: 23px;
+  height: 23px;
+  text-align: left;
+  padding-bottom: 20px;
+  box-sizing: content-box;
+
+  .titleLeft {
+    display: flex;
+    align-items: center;
+  }
+
+  .icon {
+    display: inline-block;
+    width: 20px;
+    height: 20px;
+    margin-right: 3px;
+  }
+
+  .iconWork {
+    background: url('../../../images/icon-knowlage.png') no-repeat center center;
+    background-size: contain;
+  }
+
+  .iconCourseware {
+    background: url('../../../images/icon-courseware.png') no-repeat center center;
+    background-size: contain;
+  }
+
+  &.line {
+    margin-top: 25px;
+    border-top: 1px solid #F2F2F2;
+    padding-top: 35px;
+
+    .more {
+      display: flex;
+      align-items: center;
+      cursor: pointer;
+      padding-left: 10px;
+      font-weight: 400;
+      font-size: max(13px, 12Px);
+      color: #999999;
+
+      &:hover {
+        color: #1677FF;
+
+        .iconP {
+          background: url('../../../images/icon-arrow-p-active.png') no-repeat center;
+          background-size: contain;
+        }
+      }
+    }
+
+    .iconP {
+      width: 8px;
+      height: 11px;
+      display: inline-block;
+      background: url('../../../images/icon-arrow-p.png') no-repeat center;
+      background-size: contain;
+      margin-left: 4px;
+    }
+
+    .swipeControll {
+      height: 25px;
+
+      .leftIcon {
+        transform: rotate(180deg);
+      }
+
+      img {
+        cursor: pointer;
+        width: 25px;
+        height: 25px;
+      }
+
+      .disabled {
+        opacity: 0.4;
+        cursor: not-allowed;
+      }
+    }
+  }
+}
+
+.listLoading {}
+
+.list {
+  display: flex;
+  flex-flow: row wrap;
+  justify-content: flex-start;
+  padding: 10px 20px 12px;
+  // padding: 0 20px 0px;
+  gap: 10px 0;
+  margin: 0 -10px 0;
+  // height: 313px;
+
+
+  &.listEmpty {
+    min-height: calc(var(--window-page-lesson-height) - 100px);
+    align-items: center;
+  }
+
+  &.listSame {
+    margin-top: 0;
+    padding-top: 0;
+  }
+
+  .empty1 {
+    // padding: 10px 0;
+  }
+
+  .itemWrap {
+    // width: calc(100% / 4);
+    width: 336px;
+    // padding-bottom: calc(100% / 3 * 0.73333);
+    // position: relative;
+
+    .itemWrapBox {
+      //   position: absolute;
+      //   left: 0;
+      //   top: 0;
+      //   width: 100%;
+      //   height: 100%;
+      padding: 0 10px;
+    }
+  }
+
+}
+
+.itemWrapBox {
+  padding: 0 10px;
+}
+
+.attendClassModal1 {
+  width: 1360px;
+  border-radius: 16px;
+  overflow: hidden;
+}
+
+.removeVisiable1 {
+  width: 432px;
+
+  :global {
+    .n-card-header {
+      font-size: max(22px, 16Px);
+    }
+  }
+
+  .studentRemove {
+    padding: 20px 40px 0;
+
+    p {
+      font-size: max(18px, 14Px);
+      color: #777777;
+      line-height: 30px;
+
+      span {
+        color: #EA4132;
+      }
+    }
+  }
+
+  .btnGroupModal {
+    padding: 32px 0;
+
+    :global {
+      .n-button {
+        height: 47px;
+        min-width: 156px;
+      }
+    }
+  }
+}
+
+.attendClassModal {
+  width: 800px;
+  border-radius: 16px;
+  overflow: hidden;
+}
+
+.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);
+  }
+}
+
+.popSelect {
+  font-size: 16px;
+  width: 200px;
+  box-shadow: 0px 2 16px 0px rgba(0, 0, 0, 0.08);
+  border-radius: 11px;
+  --n-option-height: 34px;
+
+  :global {
+    .n-base-select-option__content {
+      width: 80% !important;
+    }
+  }
+}
+
+.textBtn {
+  // background: #fff;
+  // border-radius: 8Px;
+  // padding: 4Px 0;
+  // font-size: max(16px, 13Px);
+  // color: rgba(0, 0, 0, 0.6);
+  position: relative;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  font-weight: 500;
+
+  .iconArrow {
+    display: inline-block;
+    margin-left: 8px;
+    width: 8px;
+    height: 5px;
+    background: url('@/views/prepare-lessons/images/icon-arrow-1.png') no-repeat center center / contain;
+    // transform: rotate(180deg);
+  }
+
+  &:hover,
+  &.textBtnActive {
+    // background: #D2ECFF;
+    font-weight: 600;
+    color: #131415;
+  }
+
+  &:hover {
+    color: #198CFE;
+
+    .iconArrow {
+      // transform: rotate(0deg);
+      background: url('@/views/prepare-lessons/images/icon-arrow-2.png') no-repeat center center / contain;
+    }
+  }
 }

+ 161 - 161
src/views/prepare-lessons/components/lesson-main/courseware-presets/select-related/index.tsx

@@ -1,161 +1,161 @@
-import {
-  PropType,
-  defineComponent,
-  onMounted,
-  onUnmounted,
-  reactive,
-  watch
-} from 'vue';
-import ResourceSearchGroup from './resource-search-group';
-import { NModal, NScrollbar, NSpin } from 'naive-ui';
-import styles from './index.module.less';
-import TheEmpty from '/src/components/TheEmpty';
-import { useThrottleFn } from '@vueuse/core';
-import { usePrepareStore } from '/src/store/modules/prepareLessons';
-import { api_queryOpenCoursewareByPage } from '/src/views/prepare-lessons/api';
-import Item from './item';
-import { eventGlobal } from '/src/utils';
-
-export default defineComponent({
-  name: 'share-resources',
-  emits: ['look', 'add'],
-  setup(props, { emit }) {
-    const prepareStore = usePrepareStore();
-    const state = reactive({
-      loading: false,
-      finshed: false, // 是否加载完
-      pagination: {
-        page: 1,
-        rows: 10
-      },
-      searchGroup: {
-        keyword: ''
-      },
-      tableList: [] as any,
-      editStatus: false,
-      editItem: {} as any,
-      show: false,
-      item: {} as any
-    });
-    const getList = async () => {
-      try {
-        if (!prepareStore.getSelectKey) return;
-
-        if (state.pagination.page === 1) {
-          state.loading = true;
-        }
-        // 查询公开课件列表
-        const { data } = await api_queryOpenCoursewareByPage({
-          subjectId: prepareStore.getSubjectId,
-          coursewareDetailKnowledgeId: prepareStore.getSelectKey,
-          ...state.searchGroup,
-          ...state.pagination
-        });
-        if (state.pagination.page === 1 && state.tableList.length > 0) {
-          state.tableList = [];
-        }
-        const result = data.rows || [];
-        const tempList: any = [];
-        result.forEach((item: any) => {
-          // const index = forms.tableList.findIndex(
-          //   (i: any) => i.fromChapterLessonCoursewareId === item.id
-          // );
-          const firstItem: any =
-            item.chapterKnowledgeList[0]?.chapterKnowledgeMaterialList[0];
-          tempList.push({
-            id: item.id,
-            openFlag: item.openFlag,
-            openFlagEnable: item.openFlagEnable,
-            instrumentNames: item.instrumentNames,
-            fromChapterLessonCoursewareId: item.fromChapterLessonCoursewareId,
-            name: item.name,
-            coverImg: firstItem?.bizInfo.coverImg,
-            type: firstItem?.bizInfo.type,
-            isAdd: item.addFlag
-          });
-        });
-
-        state.loading = false;
-        state.tableList.push(...tempList);
-        // console.log(result, 'result', data);
-        state.finshed = data.pages <= data.current ? true : false;
-      } catch {
-        state.loading = false;
-      }
-    };
-
-    const onSearch = async (item: any) => {
-      state.pagination.page = 1;
-      state.tableList = [];
-      state.searchGroup = Object.assign(state.searchGroup, item);
-      getList();
-    };
-
-    // 声部变化时
-    // watch(
-    //   () => prepareStore.getSubjectId,
-    //   () => {
-    //     onSearch(state.searchGroup);
-    //   }
-    // );
-
-    const throttledFn = useThrottleFn(() => {
-      state.pagination.page = state.pagination.page + 1;
-      getList();
-    }, 500);
-
-    const eventChanged = () => {
-      onSearch(state.searchGroup);
-    };
-    onMounted(() => {
-      getList();
-      eventGlobal.on('openCoursewareChanged', eventChanged);
-    });
-    onUnmounted(() => {
-      eventGlobal.off('openCoursewareChanged', eventChanged);
-    });
-    return () => (
-      <div>
-        <ResourceSearchGroup onSearch={(item: any) => onSearch(item)} />
-        <NScrollbar
-          class={[styles.listContainer, styles.listNoMusic]}
-          onScroll={(e: any) => {
-            const clientHeight = e.target?.clientHeight;
-            const scrollTop = e.target?.scrollTop;
-            const scrollHeight = e.target?.scrollHeight;
-            // 是否到底,是否加载完
-            if (
-              clientHeight + scrollTop + 20 >= scrollHeight &&
-              !state.finshed &&
-              !state.loading
-            ) {
-              throttledFn();
-            }
-          }}>
-          <NSpin show={state.loading} size={'small'}>
-            <div
-              class={[
-                styles.listSection,
-                !state.loading && state.tableList.length <= 0
-                  ? styles.emptySection
-                  : ''
-              ]}>
-              {state.tableList.length > 0 && (
-                <div class={styles.list}>
-                  {state.tableList.map((item: any) => (
-                    <Item
-                      item={item}
-                      onAdd={() => emit('add', item)}
-                      onLook={() => emit('look', item)}
-                    />
-                  ))}
-                </div>
-              )}
-              {!state.loading && state.tableList.length <= 0 && <TheEmpty />}
-            </div>
-          </NSpin>
-        </NScrollbar>
-      </div>
-    );
-  }
-});
+import {
+  PropType,
+  defineComponent,
+  onMounted,
+  onUnmounted,
+  reactive,
+  watch
+} from 'vue';
+import ResourceSearchGroup from './resource-search-group';
+import { NModal, NScrollbar, NSpin } from 'naive-ui';
+import styles from './index.module.less';
+import TheEmpty from '/src/components/TheEmpty';
+import { useThrottleFn } from '@vueuse/core';
+import { usePrepareStore } from '/src/store/modules/prepareLessons';
+import { api_queryOpenCoursewareByPage } from '/src/views/prepare-lessons/api';
+import Item from './item';
+import { eventGlobal } from '/src/utils';
+
+export default defineComponent({
+  name: 'share-resources',
+  emits: ['look', 'add'],
+  setup(props, { emit }) {
+    const prepareStore = usePrepareStore();
+    const state = reactive({
+      loading: false,
+      finshed: false, // 是否加载完
+      pagination: {
+        page: 1,
+        rows: 10
+      },
+      searchGroup: {
+        keyword: ''
+      },
+      tableList: [] as any,
+      editStatus: false,
+      editItem: {} as any,
+      show: false,
+      item: {} as any
+    });
+    const getList = async () => {
+      try {
+        if (!prepareStore.getSelectKey) return;
+
+        if (state.pagination.page === 1) {
+          state.loading = true;
+        }
+        // 查询公开课件列表
+        const { data } = await api_queryOpenCoursewareByPage({
+          instrumentId: prepareStore.getInstrumentId,
+          coursewareDetailKnowledgeId: prepareStore.getSelectKey,
+          ...state.searchGroup,
+          ...state.pagination
+        });
+        if (state.pagination.page === 1 && state.tableList.length > 0) {
+          state.tableList = [];
+        }
+        const result = data.rows || [];
+        const tempList: any = [];
+        result.forEach((item: any) => {
+          // const index = forms.tableList.findIndex(
+          //   (i: any) => i.fromChapterLessonCoursewareId === item.id
+          // );
+          const firstItem: any =
+            item.chapterKnowledgeList[0]?.chapterKnowledgeMaterialList[0];
+          tempList.push({
+            id: item.id,
+            openFlag: item.openFlag,
+            openFlagEnable: item.openFlagEnable,
+            instrumentNames: item.instrumentNames,
+            fromChapterLessonCoursewareId: item.fromChapterLessonCoursewareId,
+            name: item.name,
+            coverImg: firstItem?.bizInfo.coverImg,
+            type: firstItem?.bizInfo.type,
+            isAdd: item.addFlag
+          });
+        });
+
+        state.loading = false;
+        state.tableList.push(...tempList);
+        // console.log(result, 'result', data);
+        state.finshed = data.pages <= data.current ? true : false;
+      } catch {
+        state.loading = false;
+      }
+    };
+
+    const onSearch = async (item: any) => {
+      state.pagination.page = 1;
+      state.tableList = [];
+      state.searchGroup = Object.assign(state.searchGroup, item);
+      getList();
+    };
+
+    // 声部变化时
+    // watch(
+    //   () => prepareStore.getSubjectId,
+    //   () => {
+    //     onSearch(state.searchGroup);
+    //   }
+    // );
+
+    const throttledFn = useThrottleFn(() => {
+      state.pagination.page = state.pagination.page + 1;
+      getList();
+    }, 500);
+
+    const eventChanged = () => {
+      onSearch(state.searchGroup);
+    };
+    onMounted(() => {
+      getList();
+      eventGlobal.on('openCoursewareChanged', eventChanged);
+    });
+    onUnmounted(() => {
+      eventGlobal.off('openCoursewareChanged', eventChanged);
+    });
+    return () => (
+      <div>
+        <ResourceSearchGroup onSearch={(item: any) => onSearch(item)} />
+        <NScrollbar
+          class={[styles.listContainer, styles.listNoMusic]}
+          onScroll={(e: any) => {
+            const clientHeight = e.target?.clientHeight;
+            const scrollTop = e.target?.scrollTop;
+            const scrollHeight = e.target?.scrollHeight;
+            // 是否到底,是否加载完
+            if (
+              clientHeight + scrollTop + 20 >= scrollHeight &&
+              !state.finshed &&
+              !state.loading
+            ) {
+              throttledFn();
+            }
+          }}>
+          <NSpin show={state.loading} size={'small'}>
+            <div
+              class={[
+                styles.listSection,
+                !state.loading && state.tableList.length <= 0
+                  ? styles.emptySection
+                  : ''
+              ]}>
+              {state.tableList.length > 0 && (
+                <div class={styles.list}>
+                  {state.tableList.map((item: any) => (
+                    <Item
+                      item={item}
+                      onAdd={() => emit('add', item)}
+                      onLook={() => emit('look', item)}
+                    />
+                  ))}
+                </div>
+              )}
+              {!state.loading && state.tableList.length <= 0 && <TheEmpty />}
+            </div>
+          </NSpin>
+        </NScrollbar>
+      </div>
+    );
+  }
+});

+ 483 - 485
src/views/prepare-lessons/components/lesson-main/courseware/addCourseware.module.less

@@ -1,486 +1,484 @@
-// .btnGroup {
-//   display: flex;
-//   align-items: center;
-//   justify-content: space-between;
-//   margin-left: 22px !important;
-//   margin-right: 22px !important;
-//   // height: 40px;
-//   padding-bottom: 25px;
-//   border-bottom: 1px solid #F0F0F0;
-//   margin-bottom: 10px;
-
-
-//   .btnClassList {
-//     :global {
-//       .n-base-selection {
-//         width: 200px !important;
-//       }
-
-//       .n-base-selection-label {
-//         &::before {
-//           margin-left: 12px;
-//           content: ' ';
-//           width: max(20px, 14Px);
-//           height: max(20px, 14Px);
-//           flex-shrink: 0;
-//           background: url('../../../images/icon-class-name.png') no-repeat center;
-//           background-size: contain;
-//         }
-//       }
-
-//       .n-base-selection-input {
-//         padding-left: 8px;
-//       }
-
-//       .n-base-selection.n-base-selection--disabled {
-//         cursor: pointer;
-//       }
-
-//       .n-base-selection.n-base-selection--disabled .n-base-selection-label {
-//         background-color: #fff;
-//         cursor: pointer;
-//       }
-
-//       .n-base-selection.n-base-selection--disabled .n-base-selection-label .n-base-selection-input {
-//         color: var(--n-text-color);
-//         cursor: pointer;
-//       }
-
-//       .n-base-selection .n-base-selection-overlay {
-//         left: 24px;
-//       }
-//     }
-//   }
-
-
-//   .btnSubjectList {
-//     :global {
-//       .n-base-selection-tag-wrapper .n-tag {
-//         font-size: max(14px, 12Px);
-//       }
-//     }
-//   }
-
-//   :global {
-
-//     .n-input,
-//     .n-base-selection {
-//       --n-height: max(40px, 36Px) !important;
-//       width: 200px !important;
-//       font-size: 15px;
-//       border-radius: 8px !important;
-//     }
-
-//     .n-base-selection-input__content {
-//       font-size: max(15px, 13Px);
-//     }
-
-//     .n-button {
-//       border-radius: 8px;
-//       height: 38px;
-//       font-size: max(18px, 13Px);
-//       font-weight: 600 !important;
-//       padding: 0 27px;
-//     }
-
-//     .n-button--default-type {
-//       background: #E8F4FF;
-//       color: #0378EC;
-
-//       &:not(.n-button--disabled):hover {
-//         background: #E8F4FF;
-//       }
-
-//       .n-button__border {
-//         border: 1px solid #198CFE;
-//       }
-//     }
-
-//     .n-button--error-type {
-//       background: #FDEBED !important;
-//       color: #EC3A4E !important;
-
-//       &:not(.n-button--disabled):hover,
-//       &:not(.n-button--disabled):active {
-//         background: #FDEBED;
-//         color: #EC3A4E;
-//       }
-
-//       .n-button__border {
-//         border: 1px solid #EC3A4E;
-//       }
-//     }
-//   }
-
-//   .btnClassStart {
-//     background: #F44541 !important;
-//     color: #fff !important;
-
-//     :global {
-//       .n-button__border {
-//         border: 1px solid #F44541;
-//       }
-//     }
-//   }
-
-//   .btnItem {
-//     display: flex;
-//     align-items: center;
-//     height: max(40px, 36Px) !important;
-
-//     .btnTitle {
-//       flex-shrink: 0;
-//       font-size: max(18px, 13Px);
-//       font-weight: 600;
-
-//       span {
-//         color: #EA4132;
-//       }
-//     }
-
-//     // &:last-child {
-//     //   margin-left: 12px;
-//     // }
-//   }
-// }
-
-.tipsContainer {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  flex: 1 auto;
-  margin-right: 30px;
-  height: 40px;
-  padding: 0 16px;
-  background: #EDF7FF;
-  border-radius: 9px;
-  max-width: 600px;
-
-  .tipsLeft {
-    display: flex;
-    align-items: center;
-    font-size: max(16px, 12Px);
-    color: rgba(0, 0, 0, 0.88);
-
-
-    .tips {
-      line-height: 38px;
-    }
-  }
-
-  .iconTips {
-    margin-right: 9px;
-    width: 18px;
-    height: 18px;
-  }
-
-  .btnNoTips {
-    font-size: max(16px, 12Px);
-    font-weight: 500;
-    color: #1677FF;
-    cursor: pointer;
-  }
-}
-
-.btnGroupClass {
-  padding-top: 10px;
-}
-
-.listContainer {
-  margin: 20px 0 20px;
-  // // 52 + 28 + 38 + 38 多余10像素空间
-  // max-height: calc(var(--window-page-lesson-height) - 196px);
-
-  // .listSection {
-  //   min-height: calc(var(--window-page-lesson-height) - 196px);
-  // }
-
-  // &.listContainerDrag {
-  //   max-height: calc(var(--window-page-lesson-height) - 148px);
-
-  //   .listSection {
-  //     min-height: calc(var(--window-page-lesson-height) - 148px);
-  //   }
-  // }
-  max-height: calc(var(--window-page-lesson-height) - 40px);
-
-  .listSection {
-    min-height: calc(var(--window-page-lesson-height) - 40px);
-  }
-
-  .emptySection {
-    display: flex;
-    align-items: center;
-  }
-}
-
-
-.listItems {
-  position: relative;
-  background: #F8F9FC;
-  border-radius: 13px;
-  margin: 0 20px;
-
-  &+.listItems {
-    margin-top: 13px;
-  }
-}
-
-.knowledgePoint {
-  .btnItem {
-    padding: 13px 13px 0;
-    display: flex;
-    align-items: center;
-    // height: max(40px, 36Px) !important;
-
-    .btnTitle {
-      flex-shrink: 0;
-      font-size: max(18px, 13Px);
-      font-weight: 600;
-
-      span {
-        color: #EA4132;
-      }
-    }
-
-    :global {
-      .n-form-item-label {
-        padding-bottom: 0;
-        align-items: center;
-        font-size: max(18px, 13Px);
-        font-weight: 600;
-        padding-right: 10px;
-      }
-    }
-
-  }
-
-  :global {
-
-    .n-input,
-    .n-base-selection {
-      --n-height: max(40px, 36Px) !important;
-      width: 250px !important;
-      font-size: 15px;
-      border-radius: 8px !important;
-    }
-
-  }
-}
-
-.operationGroup {
-  position: absolute;
-  right: 13px;
-  top: 18px;
-
-  i {
-    display: inline-block;
-    width: max(27px, 24Px);
-    height: max(27px, 24Px);
-    cursor: pointer;
-  }
-
-  .iconCUp {
-    background: url('../../../images/icon-c-up.png') no-repeat center;
-    background-size: contain;
-
-    &:hover {
-      background: url('../../../images/icon-c-up-active.png') no-repeat center;
-      background-size: contain;
-    }
-  }
-
-  .iconCDown {
-    background: url('../../../images/icon-c-down.png') no-repeat center;
-    background-size: contain;
-
-    &:hover {
-      background: url('../../../images/icon-c-down-active.png') no-repeat center;
-      background-size: contain;
-    }
-  }
-
-  .iconCRemove {
-    background: url('../../../images/icon-c-delete.png') no-repeat center;
-    background-size: contain;
-
-    &:hover {
-      background: url('../../../images/icon-c-delete-active.png') no-repeat center;
-      background-size: contain;
-    }
-  }
-}
-
-.addKnowledgePoint {
-  margin: 20px;
-  width: calc(100% - 40px) !important;
-  --n-border-radius: 7px !important;
-  --n-height: max(40px, 36Px) !important;
-  font-weight: 600 !important;
-  --n-font-size: max(14px, 12Px) !important;
-  color: #0378EC;
-  background-color: #E8F4FF !important;
-
-  .iconCAdd {
-    width: max(13px, 11Px);
-    height: max(14px, 12Px);
-    margin-right: 8px;
-    background: url('../../../images/icon-c-add.png') no-repeat center;
-    background-size: contain;
-  }
-}
-
-
-.list {
-  display: flex;
-  flex-flow: row wrap;
-  justify-content: flex-start;
-
-  padding: 17px 7px 17px;
-  display: flex;
-  flex-flow: row wrap;
-  justify-content: flex-start;
-  gap: 20px 0;
-
-
-  .itemWrap {
-    width: calc(100% / 4);
-    padding-bottom: calc(100% / 4 * 0.73333);
-    position: relative;
-
-    .itemWrapBox {
-      position: absolute;
-      left: 0;
-      top: 0;
-      width: 100%;
-      height: 100%;
-      padding: 0 6px;
-
-      &:hover {
-        .itemOperation {
-          transition: all .2s ease;
-          opacity: 1;
-          visibility: visible;
-        }
-      }
-    }
-
-    .itemOperation {
-      position: absolute;
-      top: 0;
-      right: 10px;
-      z-index: 98;
-      cursor: move;
-      opacity: 0;
-      visibility: hidden;
-      transition: all .2s ease;
-    }
-
-    .iconDelete {
-      width: 27px;
-      height: 27px;
-      margin-top: 8px;
-      margin-right: 8px;
-      cursor: pointer;
-    }
-  }
-
-  :global {
-    .card-section-container {
-      width: 100%;
-      height: 100%;
-    }
-  }
-}
-
-.attendClassModal {
-  width: 800px;
-  border-radius: 16px;
-  overflow: hidden;
-}
-
-
-.addCourseware {
-  width: 532px;
-
-  :global {
-    .n-card-header {
-      font-size: max(22px, 16Px);
-    }
-  }
-}
-
-.removeVisiable1 {
-  width: 462px;
-
-  :global {
-    .n-card-header {
-      font-size: max(22px, 16Px);
-    }
-  }
-
-  .studentRemove {
-    padding: 20px 40px 0;
-
-    p {
-      font-size: max(18px, 14Px);
-      color: #777777;
-      line-height: 30px;
-
-      span {
-        color: #EA4132;
-      }
-    }
-  }
-
-  .btnGroupModal {
-    padding: 32px 0;
-
-    :global {
-      .n-button {
-        height: 47px;
-        min-width: 156px;
-      }
-    }
-  }
-}
-
-.addMusicItem {
-  position: relative;
-  box-sizing: border-box;
-  width: 100%;
-  height: 100%;
-  border-radius: 14px;
-  background: #F9FAFD;
-  display: inline-flex;
-  transition: all .3s ease-in-out;
-  border: 1Px solid rgba(209, 216, 235, 1) !important;
-  cursor: pointer;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  flex-direction: column;
-  background-color: #fff;
-
-  img {
-    width: 30Px;
-    height: 30Px;
-  }
-
-  .addMusicName {
-    padding-top: 16px;
-    font-size: max(16px, 13Px);
-    color: #131415;
-  }
-
-  // 鼠标经过时样式
-  &:hover {
-    transform: scale(1.01);
-    transition: all .2s ease-in-out;
-    border: 1px solid rgba(0, 122, 254, 1) !important;
-  }
-}
-
-.addOtherSource {
-  width: 726px;
+// .btnGroup {
+//   display: flex;
+//   align-items: center;
+//   justify-content: space-between;
+//   margin-left: 22px !important;
+//   margin-right: 22px !important;
+//   // height: 40px;
+//   padding-bottom: 25px;
+//   border-bottom: 1px solid #F0F0F0;
+//   margin-bottom: 10px;
+
+
+//   .btnClassList {
+//     :global {
+//       .n-base-selection {
+//         width: 200px !important;
+//       }
+
+//       .n-base-selection-label {
+//         &::before {
+//           margin-left: 12px;
+//           content: ' ';
+//           width: max(20px, 14Px);
+//           height: max(20px, 14Px);
+//           flex-shrink: 0;
+//           background: url('../../../images/icon-class-name.png') no-repeat center;
+//           background-size: contain;
+//         }
+//       }
+
+//       .n-base-selection-input {
+//         padding-left: 8px;
+//       }
+
+//       .n-base-selection.n-base-selection--disabled {
+//         cursor: pointer;
+//       }
+
+//       .n-base-selection.n-base-selection--disabled .n-base-selection-label {
+//         background-color: #fff;
+//         cursor: pointer;
+//       }
+
+//       .n-base-selection.n-base-selection--disabled .n-base-selection-label .n-base-selection-input {
+//         color: var(--n-text-color);
+//         cursor: pointer;
+//       }
+
+//       .n-base-selection .n-base-selection-overlay {
+//         left: 24px;
+//       }
+//     }
+//   }
+
+
+//   .btnSubjectList {
+//     :global {
+//       .n-base-selection-tag-wrapper .n-tag {
+//         font-size: max(14px, 12Px);
+//       }
+//     }
+//   }
+
+//   :global {
+
+//     .n-input,
+//     .n-base-selection {
+//       --n-height: max(40px, 36Px) !important;
+//       width: 200px !important;
+//       font-size: 15px;
+//       border-radius: 8px !important;
+//     }
+
+//     .n-base-selection-input__content {
+//       font-size: max(15px, 13Px);
+//     }
+
+//     .n-button {
+//       border-radius: 8px;
+//       height: 38px;
+//       font-size: max(18px, 13Px);
+//       font-weight: 600 !important;
+//       padding: 0 27px;
+//     }
+
+//     .n-button--default-type {
+//       background: #E8F4FF;
+//       color: #0378EC;
+
+//       &:not(.n-button--disabled):hover {
+//         background: #E8F4FF;
+//       }
+
+//       .n-button__border {
+//         border: 1px solid #198CFE;
+//       }
+//     }
+
+//     .n-button--error-type {
+//       background: #FDEBED !important;
+//       color: #EC3A4E !important;
+
+//       &:not(.n-button--disabled):hover,
+//       &:not(.n-button--disabled):active {
+//         background: #FDEBED;
+//         color: #EC3A4E;
+//       }
+
+//       .n-button__border {
+//         border: 1px solid #EC3A4E;
+//       }
+//     }
+//   }
+
+//   .btnClassStart {
+//     background: #F44541 !important;
+//     color: #fff !important;
+
+//     :global {
+//       .n-button__border {
+//         border: 1px solid #F44541;
+//       }
+//     }
+//   }
+
+//   .btnItem {
+//     display: flex;
+//     align-items: center;
+//     height: max(40px, 36Px) !important;
+
+//     .btnTitle {
+//       flex-shrink: 0;
+//       font-size: max(18px, 13Px);
+//       font-weight: 600;
+
+//       span {
+//         color: #EA4132;
+//       }
+//     }
+
+//     // &:last-child {
+//     //   margin-left: 12px;
+//     // }
+//   }
+// }
+
+.tipsContainer {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  flex: 1 auto;
+  margin-right: 30px;
+  height: 40px;
+  padding: 0 16px;
+  background: #EDF7FF;
+  border-radius: 9px;
+  max-width: 600px;
+
+  .tipsLeft {
+    display: flex;
+    align-items: center;
+    font-size: max(16px, 12Px);
+    color: rgba(0, 0, 0, 0.88);
+
+
+    .tips {
+      line-height: 38px;
+    }
+  }
+
+  .iconTips {
+    margin-right: 9px;
+    width: 18px;
+    height: 18px;
+  }
+
+  .btnNoTips {
+    font-size: max(16px, 12Px);
+    font-weight: 500;
+    color: #1677FF;
+    cursor: pointer;
+  }
+}
+
+.btnGroupClass {
+  padding-top: 10px;
+}
+
+.listContainer {
+  margin: 20px 0 20px;
+  // // 52 + 28 + 38 + 38 多余10像素空间
+  // max-height: calc(var(--window-page-lesson-height) - 196px);
+
+  // .listSection {
+  //   min-height: calc(var(--window-page-lesson-height) - 196px);
+  // }
+
+  // &.listContainerDrag {
+  //   max-height: calc(var(--window-page-lesson-height) - 148px);
+
+  //   .listSection {
+  //     min-height: calc(var(--window-page-lesson-height) - 148px);
+  //   }
+  // }
+  max-height: calc(var(--window-page-lesson-height) - 40px);
+
+  .listSection {
+    min-height: calc(var(--window-page-lesson-height) - 40px);
+  }
+
+  .emptySection {
+    display: flex;
+    align-items: center;
+  }
+}
+
+
+.listItems {
+  position: relative;
+  background: #F8F9FC;
+  border-radius: 13px;
+  margin: 0 20px;
+
+  &+.listItems {
+    margin-top: 13px;
+  }
+}
+
+.knowledgePoint {
+  .btnItem {
+    padding: 13px 13px 0;
+    display: flex;
+    align-items: center;
+    // height: max(40px, 36Px) !important;
+
+    .btnTitle {
+      flex-shrink: 0;
+      font-size: max(18px, 13Px);
+      font-weight: 600;
+
+      span {
+        color: #EA4132;
+      }
+    }
+
+    :global {
+      .n-form-item-label {
+        padding-bottom: 0;
+        align-items: center;
+        font-size: max(18px, 13Px);
+        font-weight: 600;
+        padding-right: 10px;
+      }
+    }
+
+  }
+
+  :global {
+
+    .n-input,
+    .n-base-selection {
+      --n-height: max(40px, 36Px) !important;
+      width: 250px !important;
+      font-size: 15px;
+      border-radius: 8px !important;
+    }
+
+  }
+}
+
+.operationGroup {
+  position: absolute;
+  right: 13px;
+  top: 18px;
+
+  i {
+    display: inline-block;
+    width: max(27px, 24Px);
+    height: max(27px, 24Px);
+    cursor: pointer;
+  }
+
+  .iconCUp {
+    background: url('../../../images/icon-c-up.png') no-repeat center;
+    background-size: contain;
+
+    &:hover {
+      background: url('../../../images/icon-c-up-active.png') no-repeat center;
+      background-size: contain;
+    }
+  }
+
+  .iconCDown {
+    background: url('../../../images/icon-c-down.png') no-repeat center;
+    background-size: contain;
+
+    &:hover {
+      background: url('../../../images/icon-c-down-active.png') no-repeat center;
+      background-size: contain;
+    }
+  }
+
+  .iconCRemove {
+    background: url('../../../images/icon-c-delete.png') no-repeat center;
+    background-size: contain;
+
+    &:hover {
+      background: url('../../../images/icon-c-delete-active.png') no-repeat center;
+      background-size: contain;
+    }
+  }
+}
+
+.addKnowledgePoint {
+  margin: 20px;
+  width: calc(100% - 40px) !important;
+  --n-border-radius: 7px !important;
+  --n-height: max(40px, 36Px) !important;
+  font-weight: 600 !important;
+  --n-font-size: max(14px, 12Px) !important;
+  color: #0378EC;
+  background-color: #E8F4FF !important;
+
+  .iconCAdd {
+    width: max(13px, 11Px);
+    height: max(14px, 12Px);
+    margin-right: 8px;
+    background: url('../../../images/icon-c-add.png') no-repeat center;
+    background-size: contain;
+  }
+}
+
+
+.list {
+  display: flex;
+  flex-flow: row wrap;
+  justify-content: flex-start;
+
+  padding: 17px 7px 17px;
+  display: flex;
+  flex-flow: row wrap;
+  justify-content: flex-start;
+  gap: 20px 0;
+
+
+  .itemWrap {
+    width: calc(100% / 4);
+    padding-bottom: calc(100% / 4 * 0.73333);
+    position: relative;
+
+    .itemWrapBox {
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 100%;
+      height: 100%;
+      padding: 0 6px;
+
+      &:hover {
+        .itemOperation {
+          transition: all .2s ease;
+          opacity: 1;
+          visibility: visible;
+        }
+      }
+    }
+
+    .itemOperation {
+      position: absolute;
+      top: 8px;
+      right: 14px;
+      z-index: 98;
+      cursor: move;
+      opacity: 0;
+      visibility: hidden;
+      transition: all .2s ease;
+    }
+
+    .iconDelete {
+      width: 27px;
+      height: 27px;
+      cursor: pointer;
+    }
+  }
+
+  :global {
+    .card-section-container {
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
+
+.attendClassModal {
+  width: 800px;
+  border-radius: 16px;
+  overflow: hidden;
+}
+
+
+.addCourseware {
+  width: 532px;
+
+  :global {
+    .n-card-header {
+      font-size: max(22px, 16Px);
+    }
+  }
+}
+
+.removeVisiable1 {
+  width: 462px;
+
+  :global {
+    .n-card-header {
+      font-size: max(22px, 16Px);
+    }
+  }
+
+  .studentRemove {
+    padding: 20px 40px 0;
+
+    p {
+      font-size: max(18px, 14Px);
+      color: #777777;
+      line-height: 30px;
+
+      span {
+        color: #EA4132;
+      }
+    }
+  }
+
+  .btnGroupModal {
+    padding: 32px 0;
+
+    :global {
+      .n-button {
+        height: 47px;
+        min-width: 156px;
+      }
+    }
+  }
+}
+
+.addMusicItem {
+  position: relative;
+  box-sizing: border-box;
+  width: 100%;
+  height: 100%;
+  border-radius: 14px;
+  background: #F9FAFD;
+  display: inline-flex;
+  transition: all .3s ease-in-out;
+  border: 1Px solid rgba(209, 216, 235, 1) !important;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  background-color: #fff;
+
+  img {
+    width: 30Px;
+    height: 30Px;
+  }
+
+  .addMusicName {
+    padding-top: 16px;
+    font-size: max(16px, 13Px);
+    color: #131415;
+  }
+
+  // 鼠标经过时样式
+  &:hover {
+    transform: scale(1.01);
+    transition: all .2s ease-in-out;
+    border: 1px solid rgba(0, 122, 254, 1) !important;
+  }
+}
+
+.addOtherSource {
+  width: 726px;
 }

+ 228 - 234
src/views/prepare-lessons/model/select-music/select-item/index.tsx

@@ -1,234 +1,228 @@
-import { NScrollbar, NSpin, NTabPane, NTabs } from 'naive-ui';
-import { defineComponent, onMounted, reactive, watch } from 'vue';
-import styles from './index.module.less';
-import CardType from '@/components/card-type';
-import SearchGroup from './search-group';
-import TheEmpty from '/src/components/TheEmpty';
-import { useDebounceFn, useThrottleFn, useResizeObserver } from '@vueuse/core';
-import { usePrepareStore } from '/src/store/modules/prepareLessons';
-import { musicSheetPage } from '../../../api';
-import CardPreview from '/src/components/card-preview';
-import { favorite, materialQueryPage } from '/src/views/natural-resources/api';
-
-const formatType = (type: string) => {
-  if (type === 'shareResources') {
-    return 2;
-  } else if (type === 'myResources') {
-    return 3;
-  } else if (type === 'myCollect') {
-    return 4;
-  }
-};
-
-export default defineComponent({
-  name: 'select-music',
-  props: {
-    type: {
-      type: String,
-      default: ''
-    },
-    from: {
-      type: String,
-      default: ''
-    }
-  },
-  emits: ['add'],
-  setup(props, { emit }) {
-    const prepareStore = usePrepareStore();
-    const state = reactive({
-      searchHeight: '0px',
-      loading: false,
-      finshed: false, // 是否加载完
-      pagination: {
-        page: 1,
-        rows: 20
-      },
-      searchGroup: {
-        name: '',
-        type: 'MUSIC', //
-        musicSheetCategoriesId: '',
-        musicalInstrumentId: '',
-        sourceType: formatType(props.type),
-        status: 1,
-        versionFlag: false,
-        subjectId: null
-      },
-      tableList: [] as any,
-      show: false,
-      item: {} as any,
-      isShowAddDisabled: !prepareStore.getIsEditTrain
-    });
-    const className = 'musicSearchGroup' + +new Date();
-    const getList = async () => {
-      try {
-        if (state.pagination.page === 1) {
-          state.loading = true;
-        }
-        // material/queryPage
-        // const { data } = await musicSheetPage({
-        //   ...state.searchGroup,
-        //   ...state.pagination,
-        //   subjectId: prepareStore.getSubjectId
-        // });
-        const { data } = await materialQueryPage({
-          ...state.searchGroup,
-          ...state.pagination
-          // subjectId: prepareStore.getSubjectId
-        });
-        state.loading = false;
-        const tempRows = data.rows || [];
-        const temp: any = [];
-        tempRows.forEach((row: any) => {
-          const index = prepareStore.getTrainList.findIndex(
-            (course: any) => course.musicId === row.id
-          );
-          temp.push({
-            id: row.id,
-            coverImg: row.coverImg || row.musicSvg,
-            type: 'MUSIC',
-            title: row.name,
-            isCollect: !!row.favoriteFlag,
-            isSelected: row.sourceFrom === 'PLATFORM' ? true : false,
-            refFlag: row.refFlag,
-            content: row.id,
-            xmlFileUrl: row.xmlFileUrl,
-            exist: index !== -1 ? true : false // 是否存在
-          });
-        });
-        state.tableList.push(...temp);
-
-        state.finshed = data.pages <= data.current ? true : false;
-      } catch {
-        state.loading = false;
-      }
-    };
-
-    watch(
-      () => prepareStore.trainList,
-      () => {
-        state.tableList.forEach((item: any) => {
-          const index = prepareStore.getTrainList.findIndex(
-            (course: any) => course.musicId === item.id
-          );
-          item.exist = index !== -1 ? true : false; // 是否存在
-        });
-      },
-      {
-        deep: true,
-        immediate: true
-      }
-    );
-
-    const throttledFnSearch = useDebounceFn(item => {
-      state.pagination.page = 1;
-      state.tableList = [];
-      state.searchGroup = Object.assign(state.searchGroup, item);
-      getList();
-    }, 500);
-
-    const throttledFn = useThrottleFn(() => {
-      state.pagination.page = state.pagination.page + 1;
-      getList();
-    }, 500);
-
-    // 收藏
-    const onCollect = async (item: any) => {
-      try {
-        await favorite({
-          materialId: item.id,
-          favoriteFlag: item.isCollect ? 0 : 1,
-          type: item.type
-        });
-        item.isCollect = !item.isCollect;
-      } catch {
-        //
-      }
-    };
-
-    onMounted(() => {
-      useResizeObserver(
-        document.querySelector('.' + className) as HTMLElement,
-        (entries: any) => {
-          const entry = entries[0];
-          const { height } = entry.contentRect;
-          state.searchHeight = height + 'px';
-        }
-      );
-      if (props.type === 'homework') {
-        state.isShowAddDisabled = false;
-      }
-      getList();
-    });
-    return () => (
-      <div class={styles.selectMusic}>
-        <div class={className}>
-          <SearchGroup
-            type={props.type}
-            onSearch={(item: any) => throttledFnSearch(item)}
-          />
-        </div>
-
-        <NScrollbar
-          class={styles.listContainer}
-          style={{
-            'max-height': `calc(85vh - var(--modal-lesson-tab-height) - ${state.searchHeight} - 12px) `
-          }}
-          onScroll={(e: any) => {
-            const clientHeight = e.target?.clientHeight;
-            const scrollTop = e.target?.scrollTop;
-            const scrollHeight = e.target?.scrollHeight;
-            // 是否到底,是否加载完
-            if (
-              clientHeight + scrollTop + 20 >= scrollHeight &&
-              !state.finshed &&
-              !state.loading
-            ) {
-              throttledFn();
-            }
-          }}>
-          <NSpin show={state.loading} size={'small'}>
-            <div
-              style={{
-                'min-height': `calc(85vh - var(--modal-lesson-tab-height) - ${state.searchHeight} - 12px)`
-              }}
-              class={[
-                styles.listSection,
-                !state.loading && state.tableList.length <= 0
-                  ? styles.emptySection
-                  : ''
-              ]}>
-              {state.tableList.length > 0 && (
-                <div class={styles.list}>
-                  {state.tableList.map((item: any) => (
-                    <CardType
-                      isShowAdd
-                      isShowCollect
-                      item={item}
-                      // isShowAddDisabled={state.isShowAddDisabled}
-                      onAdd={() => emit('add', item)}
-                      disabledMouseHover={false}
-                      onClick={() => {
-                        if (item.type === 'IMG') return;
-                        state.show = true;
-                        state.item = item;
-                      }}
-                      onCollect={(item: any) => onCollect(item)}
-                    />
-                  ))}
-                </div>
-              )}
-              {!state.loading && state.tableList.length <= 0 && <TheEmpty />}
-            </div>
-          </NSpin>
-        </NScrollbar>
-
-        {/* 弹窗查看 */}
-        <CardPreview
-          from={props.from}
-          v-model:show={state.show}
-          item={state.item}
-        />
-      </div>
-    );
-  }
-});
+import { NScrollbar, NSpin, NTabPane, NTabs } from 'naive-ui';
+import { defineComponent, onMounted, reactive, watch } from 'vue';
+import styles from './index.module.less';
+import CardType from '@/components/card-type';
+import SearchGroup from './search-group';
+import TheEmpty from '/src/components/TheEmpty';
+import { useDebounceFn, useThrottleFn, useResizeObserver } from '@vueuse/core';
+import { usePrepareStore } from '/src/store/modules/prepareLessons';
+import { musicSheetPage } from '../../../api';
+import CardPreview from '/src/components/card-preview';
+import { favorite, materialQueryPage } from '/src/views/natural-resources/api';
+
+const formatType = (type: string) => {
+  if (type === 'shareResources') {
+    return 2;
+  } else if (type === 'myResources') {
+    return 3;
+  } else if (type === 'myCollect') {
+    return 4;
+  }
+};
+
+export default defineComponent({
+  name: 'select-music',
+  props: {
+    type: {
+      type: String,
+      default: ''
+    },
+    from: {
+      type: String,
+      default: ''
+    }
+  },
+  emits: ['add'],
+  setup(props, { emit }) {
+    const prepareStore = usePrepareStore();
+    const state = reactive({
+      searchHeight: '0px',
+      loading: false,
+      finshed: false, // 是否加载完
+      pagination: {
+        page: 1,
+        rows: 20
+      },
+      searchGroup: {
+        name: '',
+        type: 'MUSIC', //
+        musicSheetCategoriesId: '',
+        musicalInstrumentId: '',
+        sourceType: formatType(props.type),
+        status: 1,
+        versionFlag: false,
+        subjectId: null
+      },
+      tableList: [] as any,
+      show: false,
+      item: {} as any,
+      isShowAddDisabled: !prepareStore.getIsEditTrain
+    });
+    const className = 'musicSearchGroup' + +new Date();
+    const getList = async () => {
+      try {
+        if (state.pagination.page === 1) {
+          state.loading = true;
+        }
+        const { data } = await materialQueryPage({
+          ...state.searchGroup,
+          ...state.pagination
+        });
+        state.loading = false;
+        if (data.current === 1 && state.tableList.length > 0) return;
+        const tempRows = data.rows || [];
+        const temp: any = [];
+        tempRows.forEach((row: any) => {
+          const index = prepareStore.getTrainList.findIndex(
+            (course: any) => course.musicId === row.id
+          );
+          temp.push({
+            id: row.id,
+            coverImg: row.coverImg || row.musicSvg,
+            type: 'MUSIC',
+            title: row.name,
+            isCollect: !!row.favoriteFlag,
+            isSelected: row.sourceFrom === 'PLATFORM' ? true : false,
+            refFlag: row.refFlag,
+            content: row.id,
+            xmlFileUrl: row.xmlFileUrl,
+            exist: index !== -1 ? true : false // 是否存在
+          });
+        });
+        state.tableList.push(...temp);
+
+        state.finshed = data.pages <= data.current ? true : false;
+      } catch {
+        state.loading = false;
+      }
+    };
+
+    watch(
+      () => prepareStore.trainList,
+      () => {
+        state.tableList.forEach((item: any) => {
+          const index = prepareStore.getTrainList.findIndex(
+            (course: any) => course.musicId === item.id
+          );
+          item.exist = index !== -1 ? true : false; // 是否存在
+        });
+      },
+      {
+        deep: true,
+        immediate: true
+      }
+    );
+
+    const throttledFnSearch = useDebounceFn(item => {
+      state.pagination.page = 1;
+      state.tableList = [];
+      state.searchGroup = Object.assign(state.searchGroup, item);
+      getList();
+    }, 500);
+
+    const throttledFn = useThrottleFn(() => {
+      state.pagination.page = state.pagination.page + 1;
+      getList();
+    }, 500);
+
+    // 收藏
+    const onCollect = async (item: any) => {
+      try {
+        await favorite({
+          materialId: item.id,
+          favoriteFlag: item.isCollect ? 0 : 1,
+          type: item.type
+        });
+        item.isCollect = !item.isCollect;
+      } catch {
+        //
+      }
+    };
+
+    onMounted(() => {
+      useResizeObserver(
+        document.querySelector('.' + className) as HTMLElement,
+        (entries: any) => {
+          const entry = entries[0];
+          const { height } = entry.contentRect;
+          state.searchHeight = height + 'px';
+        }
+      );
+      if (props.type === 'homework') {
+        state.isShowAddDisabled = false;
+      }
+      getList();
+    });
+    return () => (
+      <div class={styles.selectMusic}>
+        <div class={className}>
+          <SearchGroup
+            type={props.type}
+            onSearch={(item: any) => throttledFnSearch(item)}
+          />
+        </div>
+
+        <NScrollbar
+          class={styles.listContainer}
+          style={{
+            'max-height': `calc(85vh - var(--modal-lesson-tab-height) - ${state.searchHeight} - 12px) `
+          }}
+          onScroll={(e: any) => {
+            const clientHeight = e.target?.clientHeight;
+            const scrollTop = e.target?.scrollTop;
+            const scrollHeight = e.target?.scrollHeight;
+            // 是否到底,是否加载完
+            if (
+              clientHeight + scrollTop + 20 >= scrollHeight &&
+              !state.finshed &&
+              !state.loading
+            ) {
+              throttledFn();
+            }
+          }}>
+          <NSpin show={state.loading} size={'small'}>
+            <div
+              style={{
+                'min-height': `calc(85vh - var(--modal-lesson-tab-height) - ${state.searchHeight} - 12px)`
+              }}
+              class={[
+                styles.listSection,
+                !state.loading && state.tableList.length <= 0
+                  ? styles.emptySection
+                  : ''
+              ]}>
+              {state.tableList.length > 0 && (
+                <div class={styles.list}>
+                  {state.tableList.map((item: any) => (
+                    <CardType
+                      isShowAdd
+                      isShowCollect
+                      item={item}
+                      // isShowAddDisabled={state.isShowAddDisabled}
+                      onAdd={() => emit('add', item)}
+                      disabledMouseHover={false}
+                      onClick={() => {
+                        if (item.type === 'IMG') return;
+                        state.show = true;
+                        state.item = item;
+                      }}
+                      onCollect={(item: any) => onCollect(item)}
+                    />
+                  ))}
+                </div>
+              )}
+              {!state.loading && state.tableList.length <= 0 && <TheEmpty />}
+            </div>
+          </NSpin>
+        </NScrollbar>
+
+        {/* 弹窗查看 */}
+        <CardPreview
+          from={props.from}
+          v-model:show={state.show}
+          item={state.item}
+        />
+      </div>
+    );
+  }
+});

+ 249 - 245
src/views/xiaoku-ai/index.module.less

@@ -1,246 +1,250 @@
-.container {
-  display: flex;
-  flex-direction: column;
-  background: #FFFFFF;
-  border-radius: 20px;
-  min-height: 100%;
-}
-
-.tools {
-  padding: 32px 32px 20px 32px;
-  display: flex;
-  align-items: flex-start;
-  flex-shrink: 0;
-
-  :global {
-    .n-input {
-      margin-left: auto;
-      width: 360px;
-    }
-
-    .n-input__input-el {
-      height: 100%;
-      line-height: 100%;
-    }
-
-    .n-button.n-button--disabled {
-      cursor: initial;
-      padding: 0;
-    }
-  }
-
-  .tagWrap {
-    flex: 1;
-    margin-right: 20px;
-  }
-
-  .tags {
-
-    .firstButton {
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      height: 100%;
-      font-size: max(18px, 13Px);
-      color: #999999;
-      line-height: 25px;
-    }
-
-    padding: 12px 0;
-
-    :global {
-      .n-button {
-        min-width: 102px;
-        height: 37px;
-        padding: 0 24px;
-        font-size: max(18px, 13Px);
-      }
-    }
-  }
-}
-
-.content {
-  flex: 1;
-  // padding: 20px 36px 36px 36px;
-  padding: 0 6px 36px;
-
-  &.loadingContent {
-    min-height: 50vh;
-  }
-
-  gap: 50px 0;
-  display: flex;
-  flex-flow: row wrap;
-  justify-content: flex-start;
-  margin-left: -12px;
-  margin-right: -12px;
-
-  .itemWrap {
-    width: calc(100% / 6);
-    padding-bottom: calc(100% / 6 * 0.909923);
-    position: relative;
-
-    .itemWrapBox {
-      position: absolute;
-      left: 0;
-      top: 0;
-      width: 100%;
-      height: 100%;
-      padding: 0 12px;
-    }
-  }
-}
-
-// 214px
-// 223px  + 38
-
-.item {
-  margin: 0 auto;
-  position: relative;
-  width: 214px;
-  cursor: pointer;
-  transition: all .3s;
-
-  .cover {
-    position: relative;
-    overflow: hidden;
-
-    &::before {
-      content: '';
-      position: absolute;
-      top: 107px;
-      left: 0;
-      width: 214px;
-      height: 214px;
-      background: #DDF2FF;
-      border-radius: 50%;
-    }
-  }
-
-  &:hover {
-    transform: scale(1.1);
-  }
-
-  .itemImg {
-    position: relative;
-    width: 158px;
-    height: 223px;
-    margin: auto;
-    background-color: #EDEFF2;
-    background-image: url('./icon_default.svg');
-    background-repeat: no-repeat;
-    background-position: center center;
-
-    &::before {
-      content: '';
-      position: absolute;
-      top: 4px;
-      right: -4px;
-      width: 4px;
-      height: calc(100% - 8px);
-      background-color: #C5C5C5;
-      z-index: 1;
-
-
-    }
-
-
-    &::after {
-      content: '';
-      position: absolute;
-      top: 2px;
-      right: -2px;
-      width: 4px;
-      height: calc(100% - 4px);
-      background-color: #E7E7E7;
-      z-index: 2;
-    }
-
-    .itemBg {
-      position: absolute;
-      top: 0;
-      left: 0;
-      width: 100%;
-      height: 100%;
-      z-index: 4;
-      background-repeat: no-repeat;
-      background-image: linear-gradient(to right, rgba(0, 0, 0, 0.2) 0, rgba(255, 255, 255, 0.08) 0%, transparent 0.5%), linear-gradient(to right, rgba(0, 0, 0, 0.1) 0.3%, rgba(255, 255, 255, 0.09) 1.1%, transparent 1.3%);
-      background-size: 50% 100%, 50% 100%;
-      background-position: 0% top, 9% top;
-    }
-
-    :global {
-      .n-image {
-        position: relative;
-        width: 100%;
-        height: 100%;
-        z-index: 3;
-      }
-    }
-
-    img {
-      transition: opacity .3s;
-      opacity: 0;
-    }
-
-    img[data-loaded="true"] {
-      opacity: 1;
-    }
-
-
-  }
-
-  .itemName {
-    margin-top: 16px;
-    font-size: max(16px, 12Px);
-    line-height: 22px;
-    font-weight: 500;
-    color: #333;
-    text-align: center;
-  }
-}
-
-.popSelect1 {
-  font-size: 16px;
-  width: 240px;
-  // max-height: 500px;
-  // overflow-y: scroll;
-  box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.08);
-  border-radius: 11px;
-  --n-option-height: 34px;
-
-  :global {
-    .n-base-select-option__content {
-      width: 80% !important;
-    }
-  }
-}
-
-.textBtn {
-  .iconArrow {
-    display: inline-block;
-    margin-left: 8px;
-    margin-top: 2px;
-    width: 8px;
-    height: 5px;
-    background: url('../xiaoku-music/images/icon-arrow.svg') no-repeat center center / contain;
-    transform: rotate(180deg);
-    color: #131415;
-    fill: #131415;
-  }
-
-  &:hover,
-  &.textBtnActive {
-    background: #198CFE !important;
-    font-weight: 500 !important;
-    color: #fff !important;
-
-    .iconArrow {
-      transform: rotate(0deg);
-      background: url('../xiaoku-music/images/icon-arrow2.svg') no-repeat center center / contain;
-      color: #fff;
-      fill: #fff;
-      margin-top: 0;
-    }
-  }
+.container {
+  display: flex;
+  flex-direction: column;
+  background: #FFFFFF;
+  border-radius: 20px;
+  min-height: 100%;
+}
+
+.tools {
+  padding: 32px 32px 20px 32px;
+  display: flex;
+  align-items: flex-start;
+  flex-shrink: 0;
+
+  :global {
+    .n-input {
+      margin-left: auto;
+      width: 360px;
+    }
+
+    .n-input__input-el {
+      height: 100%;
+      line-height: 100%;
+    }
+
+    .n-button.n-button--disabled {
+      cursor: initial;
+      padding: 0;
+    }
+  }
+
+  .tagWrap {
+    flex: 1;
+    margin-right: 20px;
+  }
+
+  .tags {
+
+    .firstButton {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      height: 100%;
+      font-size: max(18px, 13Px);
+      color: #999999;
+      line-height: 25px;
+    }
+
+    padding: 12px 0;
+
+    :global {
+      .n-button {
+        min-width: 102px;
+        height: 37px;
+        padding: 0 24px;
+        font-size: max(18px, 13Px);
+      }
+
+      .n-button--primary-type {
+        font-weight: 500 !important;
+      }
+    }
+  }
+}
+
+.content {
+  flex: 1;
+  // padding: 20px 36px 36px 36px;
+  padding: 0 6px 36px;
+
+  &.loadingContent {
+    min-height: 50vh;
+  }
+
+  gap: 50px 0;
+  display: flex;
+  flex-flow: row wrap;
+  justify-content: flex-start;
+  margin-left: -12px;
+  margin-right: -12px;
+
+  .itemWrap {
+    width: calc(100% / 6);
+    padding-bottom: calc(100% / 6 * 0.909923);
+    position: relative;
+
+    .itemWrapBox {
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 100%;
+      height: 100%;
+      padding: 0 12px;
+    }
+  }
+}
+
+// 214px
+// 223px  + 38
+
+.item {
+  margin: 0 auto;
+  position: relative;
+  width: 214px;
+  cursor: pointer;
+  transition: all .3s;
+
+  .cover {
+    position: relative;
+    overflow: hidden;
+
+    &::before {
+      content: '';
+      position: absolute;
+      top: 107px;
+      left: 0;
+      width: 214px;
+      height: 214px;
+      background: #DDF2FF;
+      border-radius: 50%;
+    }
+  }
+
+  &:hover {
+    transform: scale(1.1);
+  }
+
+  .itemImg {
+    position: relative;
+    width: 158px;
+    height: 223px;
+    margin: auto;
+    background-color: #EDEFF2;
+    background-image: url('./icon_default.svg');
+    background-repeat: no-repeat;
+    background-position: center center;
+
+    &::before {
+      content: '';
+      position: absolute;
+      top: 4px;
+      right: -4px;
+      width: 4px;
+      height: calc(100% - 8px);
+      background-color: #C5C5C5;
+      z-index: 1;
+
+
+    }
+
+
+    &::after {
+      content: '';
+      position: absolute;
+      top: 2px;
+      right: -2px;
+      width: 4px;
+      height: calc(100% - 4px);
+      background-color: #E7E7E7;
+      z-index: 2;
+    }
+
+    .itemBg {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      z-index: 4;
+      background-repeat: no-repeat;
+      background-image: linear-gradient(to right, rgba(0, 0, 0, 0.2) 0, rgba(255, 255, 255, 0.08) 0%, transparent 0.5%), linear-gradient(to right, rgba(0, 0, 0, 0.1) 0.3%, rgba(255, 255, 255, 0.09) 1.1%, transparent 1.3%);
+      background-size: 50% 100%, 50% 100%;
+      background-position: 0% top, 9% top;
+    }
+
+    :global {
+      .n-image {
+        position: relative;
+        width: 100%;
+        height: 100%;
+        z-index: 3;
+      }
+    }
+
+    img {
+      transition: opacity .3s;
+      opacity: 0;
+    }
+
+    img[data-loaded="true"] {
+      opacity: 1;
+    }
+
+
+  }
+
+  .itemName {
+    margin-top: 16px;
+    font-size: max(16px, 12Px);
+    line-height: 22px;
+    font-weight: 500;
+    color: #333;
+    text-align: center;
+  }
+}
+
+.popSelect1 {
+  font-size: 16px;
+  width: 240px;
+  // max-height: 500px;
+  // overflow-y: scroll;
+  box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.08);
+  border-radius: 11px;
+  --n-option-height: 34px;
+
+  :global {
+    .n-base-select-option__content {
+      width: 80% !important;
+    }
+  }
+}
+
+.textBtn {
+  .iconArrow {
+    display: inline-block;
+    margin-left: 8px;
+    margin-top: 2px;
+    width: 8px;
+    height: 5px;
+    background: url('../xiaoku-music/images/icon-arrow.svg') no-repeat center center / contain;
+    transform: rotate(180deg);
+    color: #131415;
+    fill: #131415;
+  }
+
+  &:hover,
+  &.textBtnActive {
+    background: #198CFE !important;
+    font-weight: 500 !important;
+    color: #fff !important;
+
+    .iconArrow {
+      transform: rotate(0deg);
+      background: url('../xiaoku-music/images/icon-arrow2.svg') no-repeat center center / contain;
+      color: #fff;
+      fill: #fff;
+      margin-top: 0;
+    }
+  }
 }