瀏覽代碼

添加优化

lex 7 月之前
父節點
當前提交
c5232d8e59

+ 1 - 1
public/version.json

@@ -1 +1 @@
-{"version":1723799082701}
+{"version":1724051440353}

+ 22 - 5
src/components/layout/index.module.less

@@ -325,8 +325,8 @@
     padding-bottom: 20px;
 
     .teacherIcon {
-      width: 48px;
-      height: 48px;
+      width: 56px;
+      height: 56px;
       border-radius: 50%;
       border: 1px solid #ffffff;
       overflow: hidden;
@@ -335,14 +335,31 @@
 
     .teacherName {
       flex: 1;
-      font-size: 22px;
+      font-size: max(17px, 13Px);
       font-weight: 600;
       color: #333333;
-      margin-left: 16px;
       overflow: hidden;
       text-overflow: ellipsis;
       white-space: nowrap;
     }
+
+    .userInfos {
+      margin-left: 16px;
+      display: flex;
+      align-items: flex-start;
+      flex-direction: column;
+
+      .roleType {
+        margin-top: 3px;
+        font-size: max(12px, 11Px);
+        color: #2089FF;
+        background: #E8F4FF;
+        border-radius: 3px;
+        border: 1px solid rgba(25, 140, 254, 0.5);
+        padding: 0 4px;
+        line-height: 1.3;
+      }
+    }
   }
 
   .propWrapList {
@@ -617,4 +634,4 @@
 
 .popBox {
   z-index: 9999;
-}
+}

+ 20 - 9
src/components/layout/layoutTop.tsx

@@ -42,6 +42,7 @@ import { usePrepareStore } from '/src/store/modules/prepareLessons';
 import { schoolDetail } from '/src/views/studentList/api';
 import AddStudentModel from '/src/views/studentList/modals/addStudentModel';
 import { modalClickMask } from '/src/state';
+import { teacherJobType } from '/src/utils/contants';
 
 export default defineComponent({
   name: 'layoutTop',
@@ -380,14 +381,23 @@ export default defineComponent({
                     class={styles.teacherIcon}
                     src={info.value.avatar ? info.value.avatar : teacherIcon}
                     previewDisabled></NImage>
-                  <NTooltip class={styles.nameTool}>
-                    {{
-                      trigger: () => (
-                        <p class={styles.teacherName}>{info.value.nickname}</p>
-                      ),
-                      default: () => info.value.nickname
-                    }}
-                  </NTooltip>
+                  <div class={styles.userInfos}>
+                    <NTooltip class={styles.nameTool}>
+                      {{
+                        trigger: () => (
+                          <p class={styles.teacherName}>
+                            {info.value.nickname}
+                          </p>
+                        ),
+                        default: () => info.value.nickname
+                      }}
+                    </NTooltip>
+                    {info.value.teacherJobType && (
+                      <span class={styles.roleType}>
+                        {teacherJobType[info.value.teacherJobType]}
+                      </span>
+                    )}
+                  </div>
                 </div>
                 <div class={styles.propWrapList}>
                   <div
@@ -399,7 +409,8 @@ export default defineComponent({
                       previewDisabled></NImage>
                     <p class={styles.smallTitle}>个人信息</p>
                   </div>
-                  {info.value.isSuperAdmin ? (
+                  {info.value.isSuperAdmin ||
+                  info.value.teacherJobType === 'HEADMASTER' ? (
                     <div
                       class={styles.propWrapItem}
                       onClick={() => {

+ 9 - 0
src/utils/contants.ts

@@ -81,3 +81,12 @@ export const audioPlayType = {
   SING: '演唱',
   PLAY_SING: '演奏+演唱'
 } as any;
+
+/**
+ * 管理权限
+ */
+export const teacherJobType = {
+  TEACHER: '音乐老师',
+  ADMIN: '管理员',
+  HEADMASTER: '校长'
+} as any;

+ 503 - 372
src/views/classList/components/testRecode.tsx

@@ -1,372 +1,503 @@
-import { defineComponent, onMounted, reactive, ref } from 'vue';
-import styles from '../index.module.less';
-import {
-  NButton,
-  NDataTable,
-  NForm,
-  NFormItem,
-  NGi,
-  NGrid,
-  NImage,
-  NModal,
-  NNumberAnimation,
-  NSelect,
-  NSpace
-} from 'naive-ui';
-import SearchInput from '@/components/searchInput';
-import CSelect from '@/components/CSelect';
-import Pagination from '@/components/pagination';
-import add from './images/add.png';
-import {
-  getNowDateAndMonday,
-  getNowDateAndSunday,
-  getTimes,
-  getMinutes,
-  getSecend
-} from '/src/utils/dateFormat';
-import { getTestList, getTrainingStat } from '../api';
-import CDatePicker from '/src/components/CDatePicker';
-import { useRoute, useRouter } from 'vue-router';
-import TheEmpty from '/src/components/TheEmpty';
-import { initCache, setCache } from '/src/hooks/use-async';
-
-export default defineComponent({
-  name: 'student-studentList',
-  setup(props, { emit }) {
-    const state = reactive({
-      searchForm: {
-        keyword: '',
-        trainingStatus: null as any,
-        vipFlag: '' as any
-      },
-      searchWord: '',
-      orchestraType: null,
-      courseTypeCode: null,
-      subjectId: null,
-      classId: null,
-      studentType: null,
-      loading: false,
-      pagination: {
-        page: 1,
-        rows: 10,
-        pageTotal: 4
-      },
-      tableList: [] as any,
-      memberNumber: 0,
-      testInfo: {
-        practiceDurationAvg: 0,
-        vipUserCount: 0,
-        practiceUserCount: 0
-      },
-      activeRow: null
-    });
-    const route = useRoute();
-    const router = useRouter();
-    const search = () => {
-      state.pagination.page = 1;
-      getInfo();
-      getList();
-      setCache({
-        current: { ...state.searchForm, timer: timer.value },
-        saveKey: 'classDetailTestRecord'
-      });
-    };
-    const timer = ref<[number, number]>([
-      getNowDateAndMonday(new Date().getTime()),
-      getNowDateAndSunday(new Date().getTime())
-    ]);
-    const onReset = () => {
-      timer.value = [
-        getNowDateAndMonday(new Date().getTime()),
-        getNowDateAndSunday(new Date().getTime())
-      ];
-      state.searchForm = {
-        keyword: '',
-        trainingStatus: null as any,
-        vipFlag: ''
-      };
-      search();
-      setCache({
-        current: { ...state.searchForm, timer: timer.value },
-        saveKey: 'classDetailTestRecord'
-      });
-    };
-
-    initCache({
-      current: { ...state.searchForm, timer: timer.value },
-      saveKey: 'classDetailTestRecord',
-      callBack: (active: any) => {
-        state.searchForm = active;
-        timer.value = active.timer;
-      }
-    });
-    const getList = async () => {
-      state.loading = true;
-      try {
-        const res = await getTestList({
-          classGroupId: route.query.id,
-          ...state.searchForm,
-          ...state.pagination,
-          ...getTimes(timer.value, ['startTime', 'endTime'], 'YYYY-MM-DD')
-        });
-
-        state.tableList = res.data.rows;
-
-        state.pagination.pageTotal = res.data.total;
-        state.loading = false;
-      } catch (e) {
-        state.loading = false;
-        console.log(e);
-      }
-    };
-
-    const getInfo = async () => {
-      try {
-        const res = await getTrainingStat({
-          classGroupId: route.query.id,
-          ...getTimes(timer.value, ['startTime', 'endTime'], 'YYYY-MM-DD')
-        });
-        state.testInfo.practiceDurationAvg = res.data.practiceDurationAvg;
-        state.testInfo.practiceUserCount = res.data.practiceUserCount;
-        state.testInfo.vipUserCount = res.data.vipUserCount;
-      } catch (e) {
-        console.log(e);
-      }
-    };
-    onMounted(() => {
-      getInfo();
-      getList();
-    });
-    const gotoStudentDetail = (row: any) => {
-      router.push({
-        path: '/classStudentRecode',
-        query: {
-          ...route.query,
-          studentId: row.studentId,
-          studentName: row.studentName
-        }
-      });
-    };
-    const columns = () => {
-      return [
-        {
-          title: '学生姓名',
-          key: 'studentName'
-        },
-        {
-          title: '手机号',
-          key: 'studentPhone'
-        },
-        {
-          title: '性别',
-          key: 'sex',
-          render(row: any) {
-            return (
-              <>
-                {row.gender + '' != 'null'
-                  ? row.gender == '0'
-                    ? '女'
-                    : '男'
-                  : '--'}
-              </>
-            );
-          }
-        },
-        {
-          title: '学生类型',
-          key: 'studentType',
-          render(row: any) {
-            return <>{row.vipFlag ? '会员' : '普通'}</>;
-          }
-        },
-        {
-          title: '练习天数',
-          key: 'practiceDays',
-          render(row: any) {
-            return <>{row.practiceDays ? row.practiceDays : 0}天</>;
-          }
-        },
-        {
-          title: '学练时长',
-          key: 'studentType',
-          render(row: any) {
-            return (
-              <>
-                {row.practiceDuration
-                  ? getMinutes(row.practiceDuration) > 0
-                    ? getMinutes(row.practiceDuration) +
-                      '分' +
-                      getSecend(row.practiceDuration) +
-                      '秒'
-                    : getSecend(row.practiceDuration) + '秒'
-                  : 0 + '秒'}
-              </>
-            );
-          }
-        },
-        {
-          title: '操作',
-          key: 'id',
-          render(row: any) {
-            return (
-              <NButton
-                text
-                type="primary"
-                onClick={() => {
-                  gotoStudentDetail(row);
-                }}>
-                详情
-              </NButton>
-            );
-          }
-        }
-      ];
-    };
-    return () => (
-      <div>
-        <div class={styles.searchList}>
-          <NForm label-placement="left" inline>
-            <NFormItem>
-              <SearchInput
-                {...{ placeholder: '请输入学生姓名' }}
-                class={styles.searchInput}
-                searchWord={state.searchForm.keyword}
-                onChangeValue={(val: string) =>
-                  (state.searchForm.keyword = val)
-                }></SearchInput>
-            </NFormItem>
-
-            <NFormItem>
-              <CSelect
-                {...({
-                  options: [
-                    {
-                      label: '全部类型',
-                      value: ''
-                    },
-                    {
-                      label: '会员',
-                      value: true
-                    },
-                    {
-                      label: '普通',
-                      value: false
-                    }
-                  ],
-                  placeholder: '学生类型',
-                  clearable: true,
-                  inline: true
-                } as any)}
-                v-model:value={state.searchForm.vipFlag}></CSelect>
-            </NFormItem>
-            <NFormItem>
-              <CDatePicker
-                v-model:value={timer.value}
-                separator={'至'}
-                type="daterange"
-                timerValue={timer.value}></CDatePicker>
-            </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>
-        <div class={['section-container']}>
-          <NGrid x-gap="12" cols={8}>
-            <NGi>
-              <div class={styles.TrainDataItem}>
-                <div>
-                  <p class={styles.TrainDataItemTitle}>
-                    <div>
-                      <span>
-                        <NNumberAnimation
-                          from={0}
-                          to={
-                            state.testInfo.practiceUserCount
-                          }></NNumberAnimation>
-                      </span>{' '}
-                      人
-                    </div>
-                  </p>
-                </div>
-                <p class={styles.TrainDataItemsubTitle}>练习人数</p>
-              </div>
-            </NGi>
-            <NGi>
-              <div class={styles.TrainDataItem}>
-                <p class={styles.TrainDataItemTitle}>
-                  <div>
-                    <span>
-                      <NNumberAnimation
-                        from={0}
-                        to={state.testInfo.vipUserCount}></NNumberAnimation>
-                    </span>{' '}
-                    人
-                  </div>
-                </p>
-                <p class={styles.TrainDataItemsubTitle}>会员人数</p>
-              </div>
-            </NGi>
-            <NGi>
-              <div class={styles.TrainDataItem}>
-                <p class={styles.TrainDataItemTitle}>
-                  {getMinutes(state.testInfo.practiceDurationAvg) > 0 ? (
-                    <div>
-                      <span>
-                        <NNumberAnimation
-                          from={0}
-                          to={getMinutes(
-                            state.testInfo.practiceDurationAvg
-                          )}></NNumberAnimation>
-                      </span>{' '}
-                      分
-                    </div>
-                  ) : null}
-                  <div>
-                    <span>
-                      <NNumberAnimation
-                        from={0}
-                        to={getSecend(
-                          state.testInfo.practiceDurationAvg
-                        )}></NNumberAnimation>
-                    </span>{' '}
-                    秒
-                  </div>
-                </p>
-                <p class={styles.TrainDataItemsubTitle}>平均每天练习时长</p>
-              </div>
-            </NGi>
-          </NGrid>
-        </div>
-        <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>
-      </div>
-    );
-  }
-});
+import { defineComponent, nextTick, onMounted, reactive, ref } from 'vue';
+import styles from '../index.module.less';
+import {
+  NButton,
+  NDataTable,
+  NForm,
+  NFormItem,
+  NGi,
+  NGrid,
+  NImage,
+  NModal,
+  NNumberAnimation,
+  NSelect,
+  NSpace,
+  NTooltip
+} from 'naive-ui';
+import SearchInput from '@/components/searchInput';
+import CSelect from '@/components/CSelect';
+import Pagination from '@/components/pagination';
+import add from './images/add.png';
+import {
+  getNowDateAndMonday,
+  getNowDateAndSunday,
+  getTimes,
+  getMinutes,
+  getSecend
+} from '/src/utils/dateFormat';
+import { getTestList, getTrainingStat } from '../api';
+import CDatePicker from '/src/components/CDatePicker';
+import { useRoute, useRouter } from 'vue-router';
+import TheEmpty from '/src/components/TheEmpty';
+import { initCache, setCache } from '/src/hooks/use-async';
+import iconSortDefault from '@/common/images/icon-sort-default.png';
+import iconSortDesc from '@/common/images/icon-sort-desc.png';
+import iconSortAsc from '@/common/images/icon-sort-asc.png';
+
+export default defineComponent({
+  name: 'student-studentList',
+  setup(props, { emit }) {
+    const state = reactive({
+      searchForm: {
+        ase: 0,
+        sortType: 1,
+        keyword: '',
+        trainingStatus: null as any,
+        vipFlag: '' as any
+      },
+      searchWord: '',
+      orchestraType: null,
+      courseTypeCode: null,
+      subjectId: null,
+      classId: null,
+      studentType: null,
+      loading: false,
+      pagination: {
+        page: 1,
+        rows: 10,
+        pageTotal: 4
+      },
+      tableList: [] as any,
+      memberNumber: 0,
+      testInfo: {
+        practiceDurationAvg: 0,
+        vipUserCount: 0,
+        practiceUserCount: 0
+      },
+      activeRow: null
+    });
+    const route = useRoute();
+    const router = useRouter();
+    const search = () => {
+      state.pagination.page = 1;
+      getInfo();
+      getList();
+      setCache({
+        current: { ...state.searchForm, timer: timer.value },
+        saveKey: 'classDetailTestRecord'
+      });
+    };
+    const timer = ref<[number, number]>([
+      getNowDateAndMonday(new Date().getTime()),
+      getNowDateAndSunday(new Date().getTime())
+    ]);
+    const onReset = () => {
+      timer.value = [
+        getNowDateAndMonday(new Date().getTime()),
+        getNowDateAndSunday(new Date().getTime())
+      ];
+      state.searchForm = {
+        ase: 0,
+        sortType: 1,
+        keyword: '',
+        trainingStatus: null as any,
+        vipFlag: ''
+      };
+      search();
+      setCache({
+        current: { ...state.searchForm, timer: timer.value },
+        saveKey: 'classDetailTestRecord'
+      });
+    };
+
+    initCache({
+      current: { ...state.searchForm, timer: timer.value },
+      saveKey: 'classDetailTestRecord',
+      callBack: (active: any) => {
+        state.searchForm = active;
+        timer.value = active.timer;
+      }
+    });
+    const getList = async () => {
+      state.loading = true;
+      try {
+        const res = await getTestList({
+          classGroupId: route.query.id,
+          ...state.searchForm,
+          ...state.pagination,
+          ...getTimes(timer.value, ['startTime', 'endTime'], 'YYYY-MM-DD')
+        });
+
+        state.tableList = res.data.rows;
+
+        state.pagination.pageTotal = res.data.total;
+        state.loading = false;
+      } catch (e) {
+        state.loading = false;
+        console.log(e);
+      }
+    };
+
+    const getInfo = async () => {
+      try {
+        const res = await getTrainingStat({
+          classGroupId: route.query.id,
+          ...getTimes(timer.value, ['startTime', 'endTime'], 'YYYY-MM-DD')
+        });
+        state.testInfo.practiceDurationAvg = res.data.practiceDurationAvg;
+        state.testInfo.practiceUserCount = res.data.practiceUserCount;
+        state.testInfo.vipUserCount = res.data.vipUserCount;
+      } catch (e) {
+        console.log(e);
+      }
+    };
+    onMounted(() => {
+      getInfo();
+      getList();
+
+      // nextTick(() => {
+      //   // 把默认的排序删除
+      //   const dom = document.querySelectorAll('.n-data-table-sorter');
+      //   dom.forEach((item: any) => {
+      //     item.style.display = 'none';
+      //   });
+      // });
+    });
+    const gotoStudentDetail = (row: any) => {
+      router.push({
+        path: '/classStudentRecode',
+        query: {
+          ...route.query,
+          studentId: row.studentId,
+          studentName: row.studentName
+        }
+      });
+    };
+    const practiceDaysRef = reactive({
+      title() {
+        return (
+          <NTooltip showArrow={false} placement="top-start">
+            {{
+              trigger: () => (
+                <div class={styles.cell}>
+                  练习天数
+                  <img
+                    class={styles.sortIcon}
+                    src={
+                      practiceDaysRef.sortOrder === 'descend'
+                        ? iconSortDesc
+                        : practiceDaysRef.sortOrder === 'ascend'
+                        ? iconSortAsc
+                        : iconSortDefault
+                    }
+                  />
+                </div>
+              ),
+              default:
+                practiceDaysRef.sortOrder === 'descend'
+                  ? '点击升序'
+                  : practiceDaysRef.sortOrder === 'ascend'
+                  ? '取消排序'
+                  : '点击降序'
+            }}
+          </NTooltip>
+        );
+      },
+      key: 'practiceDays',
+      sorter: true,
+      sortOrder: false as any,
+      render(row: any) {
+        return <>{row.practiceDays ? row.practiceDays : 0}天</>;
+      }
+    });
+
+    const practiceDurationRef = reactive({
+      title() {
+        return (
+          <NTooltip showArrow={false} placement="top-start">
+            {{
+              trigger: () => (
+                <div class={styles.cell}>
+                  学练时长
+                  <img
+                    class={styles.sortIcon}
+                    src={
+                      practiceDurationRef.sortOrder === 'descend'
+                        ? iconSortDesc
+                        : practiceDurationRef.sortOrder === 'ascend'
+                        ? iconSortAsc
+                        : iconSortDefault
+                    }
+                  />
+                </div>
+              ),
+              default:
+                practiceDurationRef.sortOrder === 'descend'
+                  ? '点击升序'
+                  : practiceDurationRef.sortOrder === 'ascend'
+                  ? '取消排序'
+                  : '点击降序'
+            }}
+          </NTooltip>
+        );
+      },
+      key: 'practiceDuration',
+      sorter: true,
+      sortOrder: false as any,
+      render(row: any) {
+        return (
+          <>
+            {row.practiceDuration
+              ? getMinutes(row.practiceDuration) > 0
+                ? getMinutes(row.practiceDuration) +
+                  '分' +
+                  getSecend(row.practiceDuration) +
+                  '秒'
+                : getSecend(row.practiceDuration) + '秒'
+              : 0 + '秒'}
+          </>
+        );
+      }
+    });
+    const columns = () => {
+      return [
+        {
+          title: '学生姓名',
+          key: 'studentName'
+        },
+        {
+          title: '手机号',
+          key: 'studentPhone'
+        },
+        {
+          title: '性别',
+          key: 'sex',
+          render(row: any) {
+            return (
+              <>
+                {row.gender + '' != 'null'
+                  ? row.gender == '0'
+                    ? '女'
+                    : '男'
+                  : '--'}
+              </>
+            );
+          }
+        },
+        {
+          title: '学生类型',
+          key: 'studentType',
+          render(row: any) {
+            return <>{row.vipFlag ? '会员' : '普通'}</>;
+          }
+        },
+        practiceDaysRef,
+        practiceDurationRef,
+        // {
+        //   title: '练习天数',
+        //   key: 'practiceDays',
+        //   render(row: any) {
+        //     return <>{row.practiceDays ? row.practiceDays : 0}天</>;
+        //   }
+        // },
+        // {
+        //   title: '学练时长',
+        //   key: 'studentType',
+        //   render(row: any) {
+        //     return (
+        //       <>
+        //         {row.practiceDuration
+        //           ? getMinutes(row.practiceDuration) > 0
+        //             ? getMinutes(row.practiceDuration) +
+        //               '分' +
+        //               getSecend(row.practiceDuration) +
+        //               '秒'
+        //             : getSecend(row.practiceDuration) + '秒'
+        //           : 0 + '秒'}
+        //       </>
+        //     );
+        //   }
+        // },
+        {
+          title: '操作',
+          key: 'id',
+          render(row: any) {
+            return (
+              <NButton
+                text
+                type="primary"
+                onClick={() => {
+                  gotoStudentDetail(row);
+                }}>
+                详情
+              </NButton>
+            );
+          }
+        }
+      ];
+    };
+
+    const handleSorterChange = (sroter: any) => {
+      if (!sroter) {
+        state.searchForm.ase = 0;
+        state.searchForm.sortType = 1;
+        practiceDaysRef.sortOrder = false;
+        practiceDurationRef.sortOrder = false;
+      } else {
+        const list = {
+          practiceDuration: 1,
+          practiceDays: 2
+        };
+        state.searchForm.sortType =
+          list[sroter.columnKey as 'practiceDuration' | 'practiceDays'];
+        if (sroter.columnKey == 'practiceDuration') {
+          practiceDurationRef.sortOrder = sroter.order;
+          practiceDaysRef.sortOrder = false;
+        }
+        if (sroter.columnKey == 'practiceDays') {
+          practiceDaysRef.sortOrder = sroter.order;
+          practiceDurationRef.sortOrder = false;
+        }
+        state.searchForm.ase = sroter.order == 'ascend' ? 1 : 0;
+      }
+      getList();
+    };
+    return () => (
+      <div>
+        <div class={styles.searchList}>
+          <NForm label-placement="left" inline>
+            <NFormItem>
+              <SearchInput
+                {...{ placeholder: '请输入学生姓名' }}
+                class={styles.searchInput}
+                searchWord={state.searchForm.keyword}
+                onChangeValue={(val: string) =>
+                  (state.searchForm.keyword = val)
+                }></SearchInput>
+            </NFormItem>
+
+            <NFormItem>
+              <CSelect
+                {...({
+                  options: [
+                    {
+                      label: '全部类型',
+                      value: ''
+                    },
+                    {
+                      label: '会员',
+                      value: true
+                    },
+                    {
+                      label: '普通',
+                      value: false
+                    }
+                  ],
+                  placeholder: '学生类型',
+                  clearable: true,
+                  inline: true
+                } as any)}
+                v-model:value={state.searchForm.vipFlag}></CSelect>
+            </NFormItem>
+            <NFormItem>
+              <CDatePicker
+                v-model:value={timer.value}
+                separator={'至'}
+                type="daterange"
+                timerValue={timer.value}></CDatePicker>
+            </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>
+        <div class={['section-container']}>
+          <NGrid x-gap="12" cols={8}>
+            <NGi>
+              <div class={styles.TrainDataItem}>
+                <div>
+                  <p class={styles.TrainDataItemTitle}>
+                    <div>
+                      <span>
+                        <NNumberAnimation
+                          from={0}
+                          to={
+                            state.testInfo.practiceUserCount
+                          }></NNumberAnimation>
+                      </span>{' '}
+                      人
+                    </div>
+                  </p>
+                </div>
+                <p class={styles.TrainDataItemsubTitle}>练习人数</p>
+              </div>
+            </NGi>
+            <NGi>
+              <div class={styles.TrainDataItem}>
+                <p class={styles.TrainDataItemTitle}>
+                  <div>
+                    <span>
+                      <NNumberAnimation
+                        from={0}
+                        to={state.testInfo.vipUserCount}></NNumberAnimation>
+                    </span>{' '}
+                    人
+                  </div>
+                </p>
+                <p class={styles.TrainDataItemsubTitle}>会员人数</p>
+              </div>
+            </NGi>
+            <NGi>
+              <div class={styles.TrainDataItem}>
+                <p class={styles.TrainDataItemTitle}>
+                  {getMinutes(state.testInfo.practiceDurationAvg) > 0 ? (
+                    <div>
+                      <span>
+                        <NNumberAnimation
+                          from={0}
+                          to={getMinutes(
+                            state.testInfo.practiceDurationAvg
+                          )}></NNumberAnimation>
+                      </span>{' '}
+                      分
+                    </div>
+                  ) : null}
+                  <div>
+                    <span>
+                      <NNumberAnimation
+                        from={0}
+                        to={getSecend(
+                          state.testInfo.practiceDurationAvg
+                        )}></NNumberAnimation>
+                    </span>{' '}
+                    秒
+                  </div>
+                </p>
+                <p class={styles.TrainDataItemsubTitle}>平均每天练习时长</p>
+              </div>
+            </NGi>
+          </NGrid>
+        </div>
+        <div class={[styles.tableWrap, styles.noSort]}>
+          <NDataTable
+            v-slots={{
+              empty: () => <TheEmpty></TheEmpty>
+            }}
+            class={styles.classTable}
+            loading={state.loading}
+            columns={columns()}
+            data={state.tableList}
+            onUpdate:sorter={handleSorterChange}></NDataTable>
+          <Pagination
+            v-model:page={state.pagination.page}
+            v-model:pageSize={state.pagination.rows}
+            v-model:pageTotal={state.pagination.pageTotal}
+            onList={getList}
+            sync
+          />
+        </div>
+      </div>
+    );
+  }
+});

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

@@ -900,4 +900,23 @@
 
 .updateStudent {
   width: 480px;
+}
+
+.noSort {
+  :global {
+    .n-data-table-sorter {
+      display: none !important;
+    }
+  }
+}
+
+.cell {
+  display: flex;
+  align-items: center;
+
+  .sortIcon {
+    margin-left: 7px;
+    width: 13px;
+    height: 13px;
+  }
 }

+ 1 - 0
src/views/prepare-lessons/model/select-resources/select-item/index.tsx

@@ -282,6 +282,7 @@ export default defineComponent({
             ) : (
               <ResourceSearchGroup
                 type={props.type}
+                searchGroup={props.searchGroup}
                 onSearch={(item: any, type: any) => {
                   if (type) {
                     onSearch(item);

+ 161 - 10
src/views/prepare-lessons/model/select-resources/select-item/resource-search-group/index.tsx

@@ -46,9 +46,45 @@ const ChildNodeSearch = defineComponent({
       () => props.activeRow,
       () => {
         activeRow.value = props.activeRow;
-        selectItem.value = {};
+        initActiveRow();
       }
     );
+
+    const initActiveRow = () => {
+      if (activeRow.value.activeIndex) {
+        const childList = activeRow.value.children || [];
+        childList.forEach((subject: any) => {
+          if (subject.id === activeRow.value.activeIndex) {
+            let children: any;
+            let columnName = '';
+            if (subject.children) {
+              children = [
+                {
+                  columnName: subject.children[0].columnName,
+                  name: '全部',
+                  id: ''
+                },
+                ...subject.children
+              ];
+              columnName = subject.children[0].columnName;
+
+              selectItem.value = {
+                ...subject,
+                columnName,
+                activeIndex: subject.activeIndex,
+                children
+              };
+            }
+          }
+        });
+      } else {
+        selectItem.value = {};
+      }
+    };
+
+    onMounted(() => {
+      initActiveRow();
+    });
     return () => (
       <>
         {activeRow.value?.id && (
@@ -116,6 +152,10 @@ export default defineComponent({
       >,
       default: 'shareResources'
     },
+    searchGroup: {
+      type: Object,
+      default: () => ({})
+    },
     subjectId: {
       type: String,
       default: null
@@ -176,15 +216,15 @@ export default defineComponent({
     const line = ref(0);
     const isCollapse = ref(false);
     const loadingCollapse = ref(false); // 是否加载完成
-    const musicCateRef = (el: any) => {
-      if (el?.selfElRef) {
-        divDomList.value.push(el.selfElRef.parentNode);
-      }
-    };
-    const setCollapse = (flag: boolean) => {
-      isCollapse.value = flag;
-      getLive();
-    };
+    // const musicCateRef = (el: any) => {
+    //   if (el?.selfElRef) {
+    //     divDomList.value.push(el.selfElRef.parentNode);
+    //   }
+    // };
+    // const setCollapse = (flag: boolean) => {
+    //   isCollapse.value = flag;
+    //   getLive();
+    // };
     const getLive = () => {
       try {
         divDomList.value = [...new Set(divDomList.value)];
@@ -282,6 +322,61 @@ export default defineComponent({
       }
     };
 
+    // const mapList: any = new Map();
+    const formatParentId = (id: any, list: any, ids = [] as any) => {
+      for (const item of list) {
+        if (item.children && item.children.length > 0) {
+          const cIds: any = formatParentId(id, item.children, [
+            ...ids,
+            item.id
+          ]);
+          if (cIds.includes(id)) {
+            return cIds;
+          }
+        }
+        if (item.id === id) {
+          return [...ids, id];
+        }
+        // mapList[item.id] = item.parentTagId;
+        // mapList.push()
+      }
+      return ids;
+    };
+
+    const formatParentCurrentValue = (ids: any, list: any) => {
+      for (const item of list) {
+        if (ids.includes(item.id)) {
+          if (item.children && item.children.length > 0) {
+            let lastId: any;
+            item.children.forEach((child: any) => {
+              if (ids.includes(child.id)) {
+                lastId = child.id;
+              }
+            });
+            item.activeIndex = lastId;
+          }
+        }
+        if (item.children && item.children.length > 0) {
+          formatParentCurrentValue(ids, item.children);
+        }
+      }
+    };
+
+    const formatParentresetValue = (list: any) => {
+      for (const item of list) {
+        if (item.children && item.children.length > 0) {
+          // item.children.forEach(() => {
+          //   item.activeIndex = '';
+          // });
+        }
+        item.activeIndex = '';
+
+        if (item.children && item.children.length > 0) {
+          formatParentresetValue(item.children);
+        }
+      }
+    };
+
     onMounted(async () => {
       // 场景
       const tempAudio = Object.keys(audioPlayType).map(key => {
@@ -314,6 +409,62 @@ export default defineComponent({
       }
 
       formatFirstSubject();
+      console.log(props.searchGroup, 'searchGroup - parent');
+      if (props.searchGroup.type) {
+        const tempSearchGroup = props.searchGroup;
+        forms.audioPlayTypes = tempSearchGroup?.audioPlayTypes
+          ? tempSearchGroup.audioPlayTypes.join('_')
+          : '';
+
+        if (tempSearchGroup.musicalInstrumentId) {
+          forms.subjectId = tempSearchGroup.musicalInstrumentId;
+        }
+
+        if (tempSearchGroup.bookVersionId) {
+          // forms.bookVersionId = tempSearchGroup.bookVersionId || '';
+          data.childSelectId = tempSearchGroup.bookVersionId;
+          let ids = formatParentId(data.childSelectId, data.tags);
+          console.log(ids, 'ids');
+          data.tagActiveId = ids[0];
+          const index = ids.findIndex((id: any) => id === data.childSelectId);
+          // console.log(index, 'id');
+          ids = ids.slice(0, index + 1);
+          formatParentCurrentValue(ids, data.tags);
+          data.tags.forEach((item: any) => {
+            if (item.id === data.tagActiveId) {
+              let children: any;
+              let columnName = '';
+              if (item.children) {
+                children = [
+                  {
+                    columnName: item.children[0].columnName,
+                    name: '全部',
+                    id: ''
+                  },
+                  ...item.children
+                ];
+                columnName = item.children[0].columnName;
+
+                let id: any;
+                item.children.forEach((item: any) => {
+                  if (ids.includes(item.id)) {
+                    id = item.id;
+                  }
+                });
+
+                data.selectParents = {
+                  ...item,
+                  columnName,
+                  activeIndex: id || '',
+                  children
+                };
+              } else {
+                data.selectParents = {};
+              }
+            }
+          });
+        }
+      }
       onSearch('timer');
     });
     return () => (

+ 7 - 1
src/views/setting/components/personInfo.tsx

@@ -26,6 +26,7 @@ import UploadFile from '/src/components/upload-file';
 import ForgotPassword from '../modal/forgotPassword';
 import { api_sysAreaQueryAllProvince } from '../api';
 import { modalClickMask } from '/src/state';
+import { teacherJobType } from '/src/utils/contants';
 export default defineComponent({
   name: 'setting-personInfo',
   setup() {
@@ -123,11 +124,16 @@ export default defineComponent({
           <div class={styles.headerInfo}>
             <p class={styles.headerTitle}>
               {userStore.info.nickname}
-              {userStore.info.gender !== null && (
+              {/* {userStore.info.gender !== null && (
                 <NImage
                   previewDisabled
                   class={styles.sexIcon}
                   src={userStore.info.gender ? maleIcon : femaleIcon}></NImage>
+              )} */}
+              {userStore.info.teacherJobType && (
+                <span class={styles.roleType}>
+                  {teacherJobType[userStore.info.teacherJobType]}
+                </span>
               )}
             </p>
             <p class={styles.headerSubTitle}>

+ 13 - 4
src/views/setting/components/schoolInfo/index.tsx

@@ -17,6 +17,7 @@ import styles from './index.module.less';
 import { useUserStore } from '/src/store/modules/users';
 import UploadFile from '/src/components/upload-file';
 import { Add } from '@vicons/ionicons5';
+import { teacherJobType } from '/src/utils/contants';
 import {
   api_schoolUpdate,
   api_sysAreaQueryAllProvince,
@@ -75,7 +76,7 @@ export default defineComponent({
         {
           title: '老师姓名',
           key: 'nickname',
-          width: '20%',
+          width: '15%',
           render: (row: any) => {
             return (
               <div
@@ -87,9 +88,17 @@ export default defineComponent({
           }
         },
         {
+          title: '角色',
+          key: 'jobType',
+          width: '15%',
+          render: (row: any) => {
+            return teacherJobType[row.jobType];
+          }
+        },
+        {
           title: '手机号码',
           key: 'phone',
-          width: '20%',
+          width: '15%',
           render: (row: any) => {
             return (
               <div
@@ -129,7 +138,7 @@ export default defineComponent({
         {
           title: '操作',
           key: 'titleImg',
-          width: '30%',
+          width: '25%',
           render: (row: any) => (
             <NSpace>
               <NButton
@@ -153,7 +162,7 @@ export default defineComponent({
                     onClick={() => handleChange(row)}>
                     冻结
                   </NButton>
-                  {row.jobType === 'TEACHER' && (
+                  {user.info.isSuperAdmin && !row.manageAdmin && (
                     <NButton
                       type="primary"
                       text

+ 309 - 296
src/views/setting/index.module.less

@@ -1,297 +1,310 @@
-@img: './images';
-
-.listWrap {
-  min-height: 805px;
-  padding: 32px;
-  background-color: #fff;
-  border-radius: 20px;
-
-  .customTabs {
-    :global {
-      .n-tabs-tab--active {
-        font-size: max(18px, 14Px) !important;
-
-        font-weight: 600 !important;
-        color: #131415 !important;
-      }
-
-      .n-tabs-tab {
-        font-size: max(18px, 14Px);
-        padding: 8px 0 !important;
-        font-weight: 400;
-        min-width: 50px;
-        color: #8b8d98;
-
-        &:hover {
-          color: #198cfe !important;
-        }
-      }
-
-      .n-tabs-bar {
-        // background-color: red !important;
-        width: 50px !important;
-        height: 5px !important;
-        background: url('@{img}/barIcon.png') no-repeat;
-        background-size: 50px 5px;
-      }
-    }
-  }
-}
-
-.infoWrap {
-  height: 100%;
-  padding-top: 100px;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-
-  .teacherInfoWrap {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-
-    .teacherHeadWrap {
-      position: relative;
-      width: 236px;
-      height: 132px;
-
-      .headerD {
-        width: 100%;
-        height: 100%;
-      }
-
-      .defultHeade {
-        width: 116px;
-        height: 116px;
-        overflow: hidden;
-        border-radius: 50%;
-        position: absolute;
-        top: 8px;
-        left: 60px;
-      }
-
-      .changeHead {
-        background-color: rgba(0, 0, 0, 0.7);
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        font-size: 16px;
-        color: #fff;
-        font-weight: 600;
-        transition: opacity 0.3s;
-        cursor: pointer;
-      }
-
-      .disalbedNone {
-        display: none;
-      }
-
-      .hoverNone {
-        background: transparent;
-        color: transparent;
-        transition: all 0.3s;
-
-        &:hover {
-          background-color: rgba(0, 0, 0, 0.7);
-          color: #fff;
-          transition: all 0.3s;
-        }
-      }
-
-      .uploadFile {
-        position: absolute;
-        left: 0;
-        right: 0;
-        top: 0;
-        bottom: 0;
-        opacity: 0;
-      }
-    }
-
-    .headerInfo {
-      .headerTitle {
-        font-size: 22px;
-        font-weight: 600;
-        color: #131415;
-        line-height: 28px;
-        letter-spacing: 1px;
-        margin: 18px 0 8px;
-        text-align: center;
-        display: flex;
-        flex-direction: row;
-        justify-content: center;
-        align-items: center;
-
-        .sexIcon {
-          width: 12px;
-          height: 21px;
-          margin-left: 5px;
-        }
-      }
-
-      .headerSubTitle {
-        font-size: 16px;
-        font-weight: 400;
-        color: #707a92;
-        line-height: 20px;
-        text-align: center;
-      }
-    }
-  }
-
-  .setInfo {
-    margin-top: 64px;
-    width: 1172px;
-
-    :global {
-      .n-form-item {
-        min-width: 200px;
-      }
-
-      .n-form-item-label {
-        font-size: 15px;
-        color: rgba(0, 0, 0, 0.8);
-      }
-
-      .n-input {
-        border-radius: 8px;
-
-        .n-input__input-el {
-          height: 50px;
-          font-size: 16px;
-        }
-
-        &.n-input--disabled {
-          background-color: #f5f6fa;
-          color: rgba(149, 149, 152, 1);
-
-          .n-input__input-el {
-            background-color: #F5F6FA;
-            color: rgba(0, 0, 0, 0.4);
-          }
-        }
-      }
-
-      .n-base-selection {
-        height: 50px;
-        border-radius: 8px;
-
-        .n-base-selection-label {
-          height: 50px;
-          font-size: 16px;
-        }
-      }
-
-      .n-base-selection.n-base-selection--disabled .n-base-selection-label {
-        background-color: #F5F6FA;
-        color: rgba(0, 0, 0, 0.4) !important;
-      }
-
-      .n-base-selection.n-base-selection--disabled .n-base-selection-label .n-base-selection-input {
-        color: rgba(0, 0, 0, 0.4) !important;
-      }
-    }
-  }
-}
-
-.btnList {
-  width: 100%;
-  padding: 20px 0;
-  margin-top: 30px;
-
-  .btn {
-    width: 144px;
-    height: 45px;
-    border-radius: 8px;
-    font-size: 18px;
-    font-weight: 600 !important;
-    margin-right: 24px;
-  }
-}
-
-:global {
-  .option.n-base-select-option {
-    justify-content: center;
-  }
-
-  .option.n-base-select-option.n-base-select-option--pending::before {
-    background-color: #198cfe !important;
-  }
-
-  .option.n-base-select-option.n-base-select-option--pending .n-base-select-option__content {
-    color: #fff !important;
-    text-align: center;
-  }
-}
-
-.changePwdModal {
-  border-radius: 16px;
-
-  .wrap {
-    padding: 12px 0;
-
-    :global {
-      .n-input {
-        border-radius: 5px;
-      }
-
-      .n-input .n-input__input-el {
-        height: 50px;
-      }
-
-      .n-button.n-button--disabled {
-        background: #aaa;
-      }
-    }
-  }
-
-  .sendMsg {
-    min-width: 108px;
-    height: 50px;
-  }
-
-  .pwdIcon {
-    width: 24px;
-    height: 24px;
-    cursor: pointer;
-  }
-
-  .submitBtm {
-    width: 45%;
-    height: 46px;
-  }
-}
-
-.wrap {
-  padding: 12px 0;
-
-  :global {
-    .n-input {
-      border-radius: 8px;
-    }
-
-    .n-input .n-input__input-el {
-      height: 53px;
-    }
-
-    .n-button.n-button--disabled {
-      background: #aaa;
-    }
-  }
-}
-
-.sendMsg {
-  height: 53px;
-  min-width: 108px;
-}
-
-.pwdIcon {
-  width: 24px;
-  height: 24px;
-  cursor: pointer;
-}
-
-.submitBtm {
-  width: 45%;
-  height: 47px;
+@img: './images';
+
+.listWrap {
+  min-height: 805px;
+  padding: 32px;
+  background-color: #fff;
+  border-radius: 20px;
+
+  .customTabs {
+    :global {
+      .n-tabs-tab--active {
+        font-size: max(18px, 14Px) !important;
+
+        font-weight: 600 !important;
+        color: #131415 !important;
+      }
+
+      .n-tabs-tab {
+        font-size: max(18px, 14Px);
+        padding: 8px 0 !important;
+        font-weight: 400;
+        min-width: 50px;
+        color: #8b8d98;
+
+        &:hover {
+          color: #198cfe !important;
+        }
+      }
+
+      .n-tabs-bar {
+        // background-color: red !important;
+        width: 50px !important;
+        height: 5px !important;
+        background: url('@{img}/barIcon.png') no-repeat;
+        background-size: 50px 5px;
+      }
+    }
+  }
+}
+
+.infoWrap {
+  height: 100%;
+  padding-top: 100px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+
+  .teacherInfoWrap {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+
+    .teacherHeadWrap {
+      position: relative;
+      width: 236px;
+      height: 132px;
+
+      .headerD {
+        width: 100%;
+        height: 100%;
+      }
+
+      .defultHeade {
+        width: 116px;
+        height: 116px;
+        overflow: hidden;
+        border-radius: 50%;
+        position: absolute;
+        top: 8px;
+        left: 60px;
+      }
+
+      .changeHead {
+        background-color: rgba(0, 0, 0, 0.7);
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        font-size: 16px;
+        color: #fff;
+        font-weight: 600;
+        transition: opacity 0.3s;
+        cursor: pointer;
+      }
+
+      .disalbedNone {
+        display: none;
+      }
+
+      .hoverNone {
+        background: transparent;
+        color: transparent;
+        transition: all 0.3s;
+
+        &:hover {
+          background-color: rgba(0, 0, 0, 0.7);
+          color: #fff;
+          transition: all 0.3s;
+        }
+      }
+
+      .uploadFile {
+        position: absolute;
+        left: 0;
+        right: 0;
+        top: 0;
+        bottom: 0;
+        opacity: 0;
+      }
+    }
+
+    .headerInfo {
+      .headerTitle {
+        font-size: max(18px, 15Px);
+        font-weight: 600;
+        color: #131415;
+        line-height: 28px;
+        letter-spacing: 1px;
+        margin: 18px 0 8px;
+        text-align: center;
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        align-items: center;
+
+        .sexIcon {
+          width: 12px;
+          height: 21px;
+          margin-left: 5px;
+        }
+      }
+
+
+      .roleType {
+        margin-left: 5px;
+        font-size: max(12px, 11Px);
+        color: #2089FF;
+        background: #E8F4FF;
+        border-radius: 3px;
+        border: 1px solid rgba(25, 140, 254, 0.5);
+        padding: 0 4px;
+        line-height: 1.3;
+      }
+
+
+      .headerSubTitle {
+        font-size: 16px;
+        font-weight: 400;
+        color: #707a92;
+        line-height: 20px;
+        text-align: center;
+      }
+    }
+  }
+
+  .setInfo {
+    margin-top: 64px;
+    width: 1172px;
+
+    :global {
+      .n-form-item {
+        min-width: 200px;
+      }
+
+      .n-form-item-label {
+        font-size: 15px;
+        color: rgba(0, 0, 0, 0.8);
+      }
+
+      .n-input {
+        border-radius: 8px;
+
+        .n-input__input-el {
+          height: 50px;
+          font-size: 16px;
+        }
+
+        &.n-input--disabled {
+          background-color: #f5f6fa;
+          color: rgba(149, 149, 152, 1);
+
+          .n-input__input-el {
+            background-color: #F5F6FA;
+            color: rgba(0, 0, 0, 0.4);
+          }
+        }
+      }
+
+      .n-base-selection {
+        height: 50px;
+        border-radius: 8px;
+
+        .n-base-selection-label {
+          height: 50px;
+          font-size: 16px;
+        }
+      }
+
+      .n-base-selection.n-base-selection--disabled .n-base-selection-label {
+        background-color: #F5F6FA;
+        color: rgba(0, 0, 0, 0.4) !important;
+      }
+
+      .n-base-selection.n-base-selection--disabled .n-base-selection-label .n-base-selection-input {
+        color: rgba(0, 0, 0, 0.4) !important;
+      }
+    }
+  }
+}
+
+.btnList {
+  width: 100%;
+  padding: 20px 0;
+  margin-top: 30px;
+
+  .btn {
+    width: 144px;
+    height: 45px;
+    border-radius: 8px;
+    font-size: 18px;
+    font-weight: 600 !important;
+    margin-right: 24px;
+  }
+}
+
+:global {
+  .option.n-base-select-option {
+    justify-content: center;
+  }
+
+  .option.n-base-select-option.n-base-select-option--pending::before {
+    background-color: #198cfe !important;
+  }
+
+  .option.n-base-select-option.n-base-select-option--pending .n-base-select-option__content {
+    color: #fff !important;
+    text-align: center;
+  }
+}
+
+.changePwdModal {
+  border-radius: 16px;
+
+  .wrap {
+    padding: 12px 0;
+
+    :global {
+      .n-input {
+        border-radius: 5px;
+      }
+
+      .n-input .n-input__input-el {
+        height: 50px;
+      }
+
+      .n-button.n-button--disabled {
+        background: #aaa;
+      }
+    }
+  }
+
+  .sendMsg {
+    min-width: 108px;
+    height: 50px;
+  }
+
+  .pwdIcon {
+    width: 24px;
+    height: 24px;
+    cursor: pointer;
+  }
+
+  .submitBtm {
+    width: 45%;
+    height: 46px;
+  }
+}
+
+.wrap {
+  padding: 12px 0;
+
+  :global {
+    .n-input {
+      border-radius: 8px;
+    }
+
+    .n-input .n-input__input-el {
+      height: 53px;
+    }
+
+    .n-button.n-button--disabled {
+      background: #aaa;
+    }
+  }
+}
+
+.sendMsg {
+  height: 53px;
+  min-width: 108px;
+}
+
+.pwdIcon {
+  width: 24px;
+  height: 24px;
+  cursor: pointer;
+}
+
+.submitBtm {
+  width: 45%;
+  height: 47px;
 }

+ 2 - 1
src/views/setting/index.tsx

@@ -44,7 +44,8 @@ export default defineComponent({
           <NTabPane name="person" tab="个人信息">
             <PersonInfo></PersonInfo>
           </NTabPane>
-          {user.info.isSuperAdmin && (
+          {(user.info.isSuperAdmin ||
+            user.info.teacherJobType === 'HEADMASTER') && (
             <NTabPane name="school" tab="学校设置">
               <SchoolInfo onChangeTab={onChangeTab} />
             </NTabPane>

二進制
src/views/xiaoku-music/images/icon-collect-active.png


二進制
src/views/xiaoku-music/images/icon-collect-default.png


二進制
src/views/xiaoku-music/images/icon_trans_default.png


+ 30 - 11
src/views/xiaoku-music/index.module.less

@@ -433,14 +433,23 @@
       height: 37px !important;
       background: #F5F6FA;
       --n-border: #F5F6FA !important;
-
-
     }
 
     .transBtn {
       width: 45px;
+      height: 45px;
       cursor: pointer;
       margin-right: 15px;
+      // background: url('./images/icon_trans_default.png');
+      // background-size: contain;
+
+      // &:hover {
+      //   background: url('./images/icon_trans.png');
+      //   background-size: contain;
+      // }
+      &:hover {
+        opacity: 0.7;
+      }
     }
   }
 
@@ -452,14 +461,18 @@
     transition: all .3s;
 
     &:hover {
-      transform: scale(1.1);
+      // transform: scale(1.1);
+
+      img {
+        opacity: 0.7;
+      }
     }
 
     &>img {
       display: block;
       width: 100%;
       height: 100%;
-      filter: drop-shadow(0 0 10px rgba(27, 35, 55, .1));
+      // filter: drop-shadow(0 0 10px rgba(27, 35, 55, .1));
     }
   }
 }
@@ -579,18 +592,24 @@
     fill: #131415;
   }
 
+  &:hover {
+    opacity: 0.7;
+  }
+
   &:hover,
   &.textBtnActive {
-    background: #198CFE !important;
-    font-weight: 500 !important;
-    color: #fff !important;
+    background: #F5F6FA;
+    --n-border: #F5F6FA !important;
+    --n-border-hover: #F5F6FA !important;
+    font-weight: 600 !important;
+    color: #131415 !important;
 
     .iconArrow {
       transform: rotate(0deg);
-      background: url('./images/icon-arrow2.svg') no-repeat center center / contain;
-      color: #fff;
-      fill: #fff;
+      background: url('./images/icon-arrow.svg') no-repeat center center / contain;
+      color: #131415;
+      fill: #131415;
       margin-top: 0;
     }
   }
-}
+}

+ 7 - 5
src/views/xiaoku-music/index.tsx

@@ -31,11 +31,12 @@ import icon_arrow from './images/icon_arrow.png';
 // import icon_play from './images/icon_play.png';
 // import icon_pause from './images/icon_pause.png';
 import icon_goXiaoku from './images/icon_goXiaoku.png';
-import icon_favitor from '/src/common/images/icon-collect-default.png';
-import icon_favitorActive from '/src/common/images/icon-collect-active.png';
+import icon_favitor from './images/icon-collect-default.png';
+import icon_favitorActive from './images/icon-collect-active.png';
 import icon_default from './images/icon_default.png';
 import icon_close from './images/icon-close.png';
-import icon_trans from './images/icon_trans.png';
+// import icon_trans from './images/icon_trans.png';
+import icon_trans_default from './images/icon_trans_default.png';
 import { useRoute, useRouter } from 'vue-router';
 import PlayItem from './component/play-item';
 import PlayLoading from './component/play-loading';
@@ -1027,7 +1028,7 @@ export default defineComponent({
                 <div
                   class={styles.rightBtns}
                   style={{ display: activeItem.value.id ? '' : 'none' }}>
-                  {isEnsemble.value && (
+                  {!isEnsemble.value && (
                     <NPopselect
                       options={data.trackList}
                       trigger="hover"
@@ -1066,7 +1067,8 @@ export default defineComponent({
                       }}
                       // key={item.id}
                       class={[styles.popTrans]}>
-                      <img class={[styles.transBtn]} src={icon_trans} />
+                      <img class={[styles.transBtn]} src={icon_trans_default} />
+                      {/* <i class={styles.transBtn}></i> */}
                     </NPopselect>
                   )}
                   <div class={styles.favitor} onClick={() => handleFavitor()}>

+ 2 - 2
vite.config.ts

@@ -23,8 +23,8 @@ function resolve(dir: string) {
 }
 // https://vitejs.dev/config/
 // https://github.com/vitejs/vite/issues/1930 .env
-// const proxyUrl = 'https://dev.kt.colexiu.com/';
-const proxyUrl = 'https://test.kt.colexiu.com';
+const proxyUrl = 'https://dev.kt.colexiu.com/';
+// const proxyUrl = 'https://test.kt.colexiu.com';
 // const proxyUrl = 'http://192.168.3.14:7989';
 const now = new Date().getTime();
 export default defineConfig(() => {