|
@@ -2,18 +2,22 @@ import { defineComponent, onMounted, reactive, ref } from 'vue';
|
|
|
import styles from '../index.module.less';
|
|
|
import {
|
|
|
NButton,
|
|
|
+ NCascader,
|
|
|
NDataTable,
|
|
|
NForm,
|
|
|
NFormItem,
|
|
|
NInput,
|
|
|
NInputNumber,
|
|
|
NModal,
|
|
|
+ NNumberAnimation,
|
|
|
NSpace,
|
|
|
- NTag
|
|
|
+ NTag,
|
|
|
+ NTooltip,
|
|
|
+ useMessage
|
|
|
} from 'naive-ui';
|
|
|
// import { useECharts } from '@/hooks/web/useECharts';
|
|
|
import Pagination from '/src/components/pagination';
|
|
|
-import { getPracticeRecordList } from '../api';
|
|
|
+import { api_musicPracticeRecordPageStat, getPracticeRecordList } from '../api';
|
|
|
import {
|
|
|
getNowDateAndMonday,
|
|
|
getNowDateAndSunday,
|
|
@@ -24,11 +28,18 @@ import CDatePicker from '/src/components/CDatePicker';
|
|
|
import { useUserStore } from '/src/store/modules/users';
|
|
|
import TheEmpty from '/src/components/TheEmpty';
|
|
|
import { initCache, setCache } from '/src/hooks/use-async';
|
|
|
-import { iframeDislableKeyboard } from '/src/utils';
|
|
|
+import { checkUrlType, iframeDislableKeyboard } from '/src/utils';
|
|
|
import { modalClickMask } from '/src/state';
|
|
|
// import SearchInput from '/src/components/searchInput';
|
|
|
import CSelect from '/src/components/CSelect';
|
|
|
import { evaluateDifficultArray } from '/src/utils/searchArray';
|
|
|
+import { useCatchStore } from '/src/store/modules/catchData';
|
|
|
+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';
|
|
|
+import TheTooltip from '/src/components/TheTooltip';
|
|
|
+import CardPreview from '/src/components/card-preview';
|
|
|
+import { saveAs } from 'file-saver';
|
|
|
export default defineComponent({
|
|
|
name: 'student-practiceData',
|
|
|
props: {
|
|
@@ -43,7 +54,9 @@ export default defineComponent({
|
|
|
},
|
|
|
setup(props) {
|
|
|
const userStore = useUserStore();
|
|
|
- const chartRef = ref<HTMLDivElement | null>(null);
|
|
|
+ const catchData = useCatchStore()
|
|
|
+ const message = useMessage()
|
|
|
+ // const chartRef = ref<HTMLDivElement | null>(null);
|
|
|
// const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
|
|
|
// const practiceFlag = ref(true);
|
|
|
const payForm = reactive({
|
|
@@ -64,14 +77,18 @@ export default defineComponent({
|
|
|
rows: 10,
|
|
|
pageTotal: 4
|
|
|
},
|
|
|
+ asc: null as any,
|
|
|
+ sortType: null as any,
|
|
|
searchForm: {
|
|
|
musicSheetName: '',
|
|
|
+ instrumentId: null,
|
|
|
heardLevel: null, //
|
|
|
userMusicFlag: null, // 是否生成作品
|
|
|
minScore: null,
|
|
|
maxScore: null,
|
|
|
musicStartTime: []
|
|
|
},
|
|
|
+ stat: {} as any,
|
|
|
tableList: [] as any,
|
|
|
goCourseVisiable: false
|
|
|
});
|
|
@@ -79,17 +96,134 @@ export default defineComponent({
|
|
|
getNowDateAndMonday(new Date().getTime()),
|
|
|
getNowDateAndSunday(new Date().getTime())
|
|
|
]);
|
|
|
+ const previewShow = ref(false);
|
|
|
+ const previewItem = ref({
|
|
|
+ type: '',
|
|
|
+ content: '',
|
|
|
+ title: ''
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ const toolTitleTips = (title: string, item: any) => {
|
|
|
+ return <NTooltip showArrow={false} placement="top-start">
|
|
|
+ {{
|
|
|
+ trigger: () => (
|
|
|
+ <div class={styles.cell}>
|
|
|
+ {title}
|
|
|
+ <img
|
|
|
+ class={styles.sortIcon}
|
|
|
+ src={
|
|
|
+ item.sortOrder === 'descend'
|
|
|
+ ? iconSortDesc
|
|
|
+ : item.sortOrder === 'ascend'
|
|
|
+ ? iconSortAsc
|
|
|
+ : iconSortDefault
|
|
|
+ }
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ ),
|
|
|
+ default:
|
|
|
+ item.sortOrder === 'descend'
|
|
|
+ ? '点击升序'
|
|
|
+ : item.sortOrder === 'ascend'
|
|
|
+ ? '取消排序'
|
|
|
+ : '点击降序'
|
|
|
+ }}
|
|
|
+ </NTooltip>
|
|
|
+ }
|
|
|
+
|
|
|
+ const createTimeRef = reactive({
|
|
|
+ title() {
|
|
|
+ return (
|
|
|
+ toolTitleTips('评测时间', createTimeRef)
|
|
|
+ );
|
|
|
+ },
|
|
|
+ key: 'createTime',
|
|
|
+ sorter: true,
|
|
|
+ sortOrder: false as any
|
|
|
+ });
|
|
|
+
|
|
|
+ const evaluationProgressRef = reactive({
|
|
|
+ title() {
|
|
|
+ return (
|
|
|
+ toolTitleTips('评测进度', evaluationProgressRef)
|
|
|
+ );
|
|
|
+ },
|
|
|
+ key: 'evaluationProgress',
|
|
|
+ sorter: true,
|
|
|
+ sortOrder: false as any
|
|
|
+ });
|
|
|
+
|
|
|
+ const scoreRef = reactive({
|
|
|
+ title() {
|
|
|
+ return (
|
|
|
+ toolTitleTips('评测分数', scoreRef)
|
|
|
+ );
|
|
|
+ },
|
|
|
+ key: 'score',
|
|
|
+ sorter: true,
|
|
|
+ sortOrder: false as any
|
|
|
+ });
|
|
|
+
|
|
|
+ const intonationRef = reactive({
|
|
|
+ title() {
|
|
|
+ return (
|
|
|
+ toolTitleTips('音准', intonationRef)
|
|
|
+ );
|
|
|
+ },
|
|
|
+ key: 'intonation',
|
|
|
+ sorter: true,
|
|
|
+ sortOrder: false as any,
|
|
|
+ render(row: any) {
|
|
|
+ return row.rhythmFlag ? '--' : row.intonation
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ const cadenceRef = reactive({
|
|
|
+ title() {
|
|
|
+ return (
|
|
|
+ toolTitleTips('节奏', cadenceRef)
|
|
|
+ );
|
|
|
+ },
|
|
|
+ key: 'cadence',
|
|
|
+ sorter: true,
|
|
|
+ sortOrder: false as any
|
|
|
+ });
|
|
|
+
|
|
|
+ const integrityRef = reactive({
|
|
|
+ title() {
|
|
|
+ return (
|
|
|
+ toolTitleTips('完整度', integrityRef)
|
|
|
+ );
|
|
|
+ },
|
|
|
+ key: 'integrity',
|
|
|
+ sorter: true,
|
|
|
+ sortOrder: false as any
|
|
|
+ });
|
|
|
+
|
|
|
+ const userMusicTimeRef = reactive({
|
|
|
+ title() {
|
|
|
+ return (
|
|
|
+ toolTitleTips('发布时间', userMusicTimeRef)
|
|
|
+ );
|
|
|
+ },
|
|
|
+ key: 'userMusicTime',
|
|
|
+ sorter: true,
|
|
|
+ sortOrder: false as any
|
|
|
+ });
|
|
|
+
|
|
|
const columns = () => {
|
|
|
return [
|
|
|
- {
|
|
|
- title: '时间',
|
|
|
- key: 'createTime'
|
|
|
- },
|
|
|
+ createTimeRef,
|
|
|
{
|
|
|
title: '评测曲目',
|
|
|
key: 'musicSheetName',
|
|
|
render(row: any) {
|
|
|
- return <span>{row.musicSheetName}</span>;
|
|
|
+ return <TheTooltip
|
|
|
+ maxWidth={200}
|
|
|
+ showContentWidth={300}
|
|
|
+ content={row.musicSheetName}
|
|
|
+ />;
|
|
|
}
|
|
|
},
|
|
|
// 入门:BEGINNER/进阶:ADVANCED/大师:PERFORMER"
|
|
@@ -114,83 +248,168 @@ export default defineComponent({
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
- title: '评测分数',
|
|
|
- key: 'score',
|
|
|
- render(row: any) {
|
|
|
- return <span>{row.score}</span>;
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: '音准',
|
|
|
- key: 'intonation',
|
|
|
- render(row: any) {
|
|
|
- return <span>{row.rhythmFlag ? '--' : row.intonation}</span>;
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: '节奏',
|
|
|
- key: 'cadence',
|
|
|
- render(row: any) {
|
|
|
- return <span>{row.rhythmFlag ? '--' : row.cadence}</span>;
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: '完整度',
|
|
|
- key: 'integrity',
|
|
|
- render(row: any) {
|
|
|
- return <span>{row.integrity}</span>;
|
|
|
- }
|
|
|
+ title: '乐器',
|
|
|
+ key: 'instrumentName'
|
|
|
},
|
|
|
+ evaluationProgressRef,
|
|
|
+ scoreRef,
|
|
|
+ intonationRef,
|
|
|
+ cadenceRef,
|
|
|
+ integrityRef,
|
|
|
{
|
|
|
- title: '生成作品',
|
|
|
+ title: '发布作品',
|
|
|
key: 'integrity',
|
|
|
render(row: any) {
|
|
|
return <span>{row.userMusicFlag ? '是' : '否'}</span>;
|
|
|
}
|
|
|
},
|
|
|
- {
|
|
|
- title: '生成时间',
|
|
|
- key: 'userMusicTime',
|
|
|
- render(row: any) {
|
|
|
- return <span>{row.userMusicTime || '--'}</span>;
|
|
|
- }
|
|
|
- },
|
|
|
+ userMusicTimeRef,
|
|
|
{
|
|
|
title: '操作',
|
|
|
key: 'id',
|
|
|
render(row: any) {
|
|
|
return (
|
|
|
- <NButton
|
|
|
- text
|
|
|
- type="primary"
|
|
|
- onClick={() => {
|
|
|
- gotoRecode(row);
|
|
|
- }}>
|
|
|
- 评测报告
|
|
|
- </NButton>
|
|
|
+ <NSpace>
|
|
|
+ <NButton
|
|
|
+ text
|
|
|
+ type="primary"
|
|
|
+ onClick={() => {
|
|
|
+ gotoRecode(row);
|
|
|
+ }}>
|
|
|
+ 评测报告
|
|
|
+ </NButton>
|
|
|
+ {row.videoFilePath || row.recordFilePath ? <><NButton
|
|
|
+ text
|
|
|
+ type="primary"
|
|
|
+ onClick={() => {
|
|
|
+ gotoPreview(row);
|
|
|
+ }}>
|
|
|
+ 预览作品
|
|
|
+ </NButton>
|
|
|
+ <NButton
|
|
|
+ text
|
|
|
+ type="primary"
|
|
|
+ onClick={() => {
|
|
|
+ gotoDownload(row);
|
|
|
+ }}>
|
|
|
+ 下载作品
|
|
|
+ </NButton></> : ''}
|
|
|
+
|
|
|
+ </NSpace>
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
];
|
|
|
};
|
|
|
+
|
|
|
+ // 统计排序
|
|
|
+ const handleSorterChange = (sroter: any) => {
|
|
|
+ if (!sroter.order) {
|
|
|
+ state.asc = null
|
|
|
+ state.sortType = null
|
|
|
+ evaluationProgressRef.sortOrder = false
|
|
|
+ scoreRef.sortOrder = false
|
|
|
+ createTimeRef.sortOrder = false
|
|
|
+ intonationRef.sortOrder = false
|
|
|
+ cadenceRef.sortOrder = false
|
|
|
+ integrityRef.sortOrder = false
|
|
|
+ userMusicTimeRef.sortOrder = false
|
|
|
+ } else {
|
|
|
+ // 1:综合得分,2:音准,3:节奏:4:完整度,5:评测时间 6:生成时间,7:评测进度
|
|
|
+ const template = {
|
|
|
+ score: 1,
|
|
|
+ intonation: 2,
|
|
|
+ cadence: 3,
|
|
|
+ integrity: 4,
|
|
|
+ createTime: 5,
|
|
|
+ userMusicTime: 6,
|
|
|
+ evaluationProgress: 7
|
|
|
+ } as any
|
|
|
+
|
|
|
+ state.sortType = template[sroter.columnKey]
|
|
|
+
|
|
|
+ evaluationProgressRef.sortOrder = false
|
|
|
+ scoreRef.sortOrder = false
|
|
|
+ createTimeRef.sortOrder = false
|
|
|
+ intonationRef.sortOrder = false
|
|
|
+ cadenceRef.sortOrder = false
|
|
|
+ integrityRef.sortOrder = false
|
|
|
+ userMusicTimeRef.sortOrder = false
|
|
|
+
|
|
|
+ if (sroter.columnKey == 'score') {
|
|
|
+ scoreRef.sortOrder = sroter.order
|
|
|
+ }
|
|
|
+ if (sroter.columnKey == 'createTime') {
|
|
|
+ createTimeRef.sortOrder = sroter.order
|
|
|
+ }
|
|
|
+ if (sroter.columnKey == 'intonation') {
|
|
|
+ intonationRef.sortOrder = sroter.order
|
|
|
+ }
|
|
|
+ if (sroter.columnKey == 'cadence') {
|
|
|
+ cadenceRef.sortOrder = sroter.order
|
|
|
+ }
|
|
|
+ if (sroter.columnKey == 'userMusicTime') {
|
|
|
+ userMusicTimeRef.sortOrder = sroter.order
|
|
|
+ }
|
|
|
+ if (sroter.columnKey == 'evaluationProgress') {
|
|
|
+ evaluationProgressRef.sortOrder = sroter.order
|
|
|
+ }
|
|
|
+
|
|
|
+ state.asc = sroter.order == 'ascend' ? true : false
|
|
|
+ }
|
|
|
+ getList()
|
|
|
+ }
|
|
|
+
|
|
|
const getList = async () => {
|
|
|
- const { musicStartTime, ...temp } = state.searchForm;
|
|
|
- const res = await getPracticeRecordList({
|
|
|
- userId: props.studentId,
|
|
|
- ...state.pagination,
|
|
|
- ...temp,
|
|
|
- ...getTimes(
|
|
|
- musicStartTime,
|
|
|
- ['userMusicStartTime', 'userMusicEndTime'],
|
|
|
- 'YYYY-MM-DD'
|
|
|
- ),
|
|
|
- classGroupId: props.classGroupId,
|
|
|
- feature: 'EVALUATION',
|
|
|
- ...getTimes(timer.value, ['startTime', 'endTime'], 'YYYY-MM-DD')
|
|
|
- });
|
|
|
- state.tableList = res.data.rows;
|
|
|
- state.pagination.pageTotal = res.data.total;
|
|
|
+ state.loading = true;
|
|
|
+ try {
|
|
|
+ const { musicStartTime, ...temp } = state.searchForm;
|
|
|
+ const res = await getPracticeRecordList({
|
|
|
+ userId: props.studentId,
|
|
|
+ ...state.pagination,
|
|
|
+ sortType: state.sortType,
|
|
|
+ asc: state.asc,
|
|
|
+ ...temp,
|
|
|
+
|
|
|
+ ...getTimes(
|
|
|
+ musicStartTime,
|
|
|
+ ['startTime', 'endTime'],
|
|
|
+ 'YYYY-MM-DD'
|
|
|
+ ),
|
|
|
+ classGroupId: props.classGroupId,
|
|
|
+ ...getTimes(timer.value, ['startTime', 'endTime'], 'YYYY-MM-DD')
|
|
|
+ });
|
|
|
+ state.tableList = res.data.rows;
|
|
|
+ state.pagination.pageTotal = res.data.total;
|
|
|
+ } catch {
|
|
|
+
|
|
|
+ }
|
|
|
+ state.loading = false
|
|
|
};
|
|
|
+
|
|
|
+ const getTrainingStat = async () => {
|
|
|
+ state.loading = true;
|
|
|
+ try {
|
|
|
+ const { musicStartTime, ...more } = state.searchForm
|
|
|
+ const { data } = await api_musicPracticeRecordPageStat({
|
|
|
+ userId: props.studentId,
|
|
|
+ page: state.pagination.page,
|
|
|
+ rows: state.pagination.rows,
|
|
|
+ sortType: state.sortType,
|
|
|
+ asc: state.asc,
|
|
|
+ ...more,
|
|
|
+ ...getTimes(timer, ['startTime', 'endTime'])
|
|
|
+ })
|
|
|
+
|
|
|
+ state.stat = {
|
|
|
+ evaluateFrequency: data.evaluateFrequency || 0,
|
|
|
+ publishCount: data.publishCount || 0
|
|
|
+ }
|
|
|
+ } catch {}
|
|
|
+ state.loading = false
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
const gotoRecode = (row: any) => {
|
|
|
const token = userStore.getToken;
|
|
|
reportSrc.value =
|
|
@@ -200,8 +419,43 @@ export default defineComponent({
|
|
|
}&platform=webTeacher&Authorization=${token}`;
|
|
|
payForm.detailVisiable = true;
|
|
|
};
|
|
|
+ const gotoPreview = (row: any) => {
|
|
|
+ let lookTitle = '';
|
|
|
+ if (row.videoFilePath) {
|
|
|
+ lookTitle = checkUrlType(row.videoFilePath);
|
|
|
+ } else {
|
|
|
+ lookTitle = checkUrlType(row.recordFilePath);
|
|
|
+ }
|
|
|
+ const lookUrl = row.videoFilePath || row.recordFilePath;
|
|
|
+ previewItem.value.content = lookUrl;
|
|
|
+ previewItem.value.title = row.musicSheetName;
|
|
|
+ if (lookTitle === 'video') {
|
|
|
+ previewItem.value.type = 'VIDEO';
|
|
|
+ } else if (lookTitle === 'audio') {
|
|
|
+ previewItem.value.type = 'SONG';
|
|
|
+ }
|
|
|
+ previewShow.value = true;
|
|
|
+ }
|
|
|
+ const gotoDownload = (row: any) => {
|
|
|
+ // 下载资源
|
|
|
+ const fileUrl = row.videoFilePath || row.recordFilePath;
|
|
|
+ const filename =
|
|
|
+ row.musicSheetName + '-' + row.userId;
|
|
|
+ const sfixx = fileUrl.substring(fileUrl.lastIndexOf('.'));
|
|
|
+ // 发起Fetch请求
|
|
|
+ fetch(fileUrl)
|
|
|
+ .then(response => response.blob())
|
|
|
+ .then(blob => {
|
|
|
+ saveAs(blob, (filename || new Date().getTime()) + sfixx);
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ message.error('下载失败');
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
const search = () => {
|
|
|
state.pagination.page = 1;
|
|
|
+ getTrainingStat()
|
|
|
getList();
|
|
|
setCache({
|
|
|
current: { timer: timer.value },
|
|
@@ -219,7 +473,8 @@ export default defineComponent({
|
|
|
userMusicFlag: null, // 是否生成作品
|
|
|
minScore: null,
|
|
|
maxScore: null,
|
|
|
- musicStartTime: []
|
|
|
+ musicStartTime: [],
|
|
|
+ instrumentId: null
|
|
|
};
|
|
|
search();
|
|
|
setCache({
|
|
@@ -235,8 +490,11 @@ export default defineComponent({
|
|
|
}
|
|
|
});
|
|
|
const iframeRef = ref();
|
|
|
- onMounted(() => {
|
|
|
- getList();
|
|
|
+ onMounted(async () => {
|
|
|
+ state.loading = true
|
|
|
+ await catchData.getSubjects();
|
|
|
+ await getTrainingStat()
|
|
|
+ await getList();
|
|
|
});
|
|
|
return () => (
|
|
|
<>
|
|
@@ -299,6 +557,25 @@ export default defineComponent({
|
|
|
</NFormItem>
|
|
|
|
|
|
<NFormItem>
|
|
|
+ <NCascader
|
|
|
+ to="body"
|
|
|
+ placeholder="选择乐器"
|
|
|
+ options={[
|
|
|
+ { value: '', label: '全部乐器' },
|
|
|
+ ...catchData.getSubjectList
|
|
|
+ ]}
|
|
|
+ childrenField="instruments"
|
|
|
+ checkStrategy="child"
|
|
|
+ expandTrigger="hover"
|
|
|
+ showPath={false}
|
|
|
+ clearable
|
|
|
+ v-model:value={state.searchForm.instrumentId}
|
|
|
+ onUpdate:value={(val: any, option: any, pathValues: any) => {
|
|
|
+ console.log(val, option, pathValues);
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </NFormItem>
|
|
|
+ <NFormItem>
|
|
|
<CSelect
|
|
|
{...({
|
|
|
options: [
|
|
@@ -312,7 +589,7 @@ export default defineComponent({
|
|
|
v-model:value={state.searchForm.userMusicFlag}></CSelect>
|
|
|
</NFormItem>
|
|
|
|
|
|
- <NFormItem>
|
|
|
+ {/* <NFormItem>
|
|
|
<CDatePicker
|
|
|
v-model:value={state.searchForm.musicStartTime}
|
|
|
separator={'至'}
|
|
@@ -324,7 +601,7 @@ export default defineComponent({
|
|
|
clearable: true
|
|
|
} as any)}
|
|
|
timerValue={state.searchForm.musicStartTime}></CDatePicker>
|
|
|
- </NFormItem>
|
|
|
+ </NFormItem> */}
|
|
|
|
|
|
<NFormItem>
|
|
|
<NSpace justify="end">
|
|
@@ -337,7 +614,35 @@ export default defineComponent({
|
|
|
</NSpace>
|
|
|
</NFormItem>
|
|
|
</NForm>
|
|
|
- <div class={styles.tableWrap}>
|
|
|
+ <div class={[styles.TrainDataTop, styles.TrainDataTopEvaluation]}>
|
|
|
+ <div class={styles.TrainDataTopLeft}>
|
|
|
+ <div class={styles.TrainDataItem}>
|
|
|
+ <p class={styles.TrainDataItemTitle}>
|
|
|
+ <div>
|
|
|
+ <span>
|
|
|
+ <NNumberAnimation
|
|
|
+ from={0}
|
|
|
+ to={state.stat.evaluateFrequency || 0}></NNumberAnimation>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </p>
|
|
|
+ <p class={styles.TrainDataItemsubTitle}>评测次数</p>
|
|
|
+ </div>
|
|
|
+ <div class={styles.TrainDataItem}>
|
|
|
+ <p class={styles.TrainDataItemTitle}>
|
|
|
+ <div>
|
|
|
+ <span>
|
|
|
+ <NNumberAnimation
|
|
|
+ from={0}
|
|
|
+ to={state.stat.publishCount || 0}></NNumberAnimation>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </p>
|
|
|
+ <p class={styles.TrainDataItemsubTitle}>作品数量</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class={[styles.tableWrap, styles.noSort]}>
|
|
|
<NDataTable
|
|
|
v-slots={{
|
|
|
empty: () => <TheEmpty></TheEmpty>
|
|
@@ -345,6 +650,7 @@ export default defineComponent({
|
|
|
class={styles.classTable}
|
|
|
loading={state.loading}
|
|
|
columns={columns()}
|
|
|
+ onUpdate:sorter={handleSorterChange}
|
|
|
data={state.tableList}></NDataTable>
|
|
|
<Pagination
|
|
|
v-model:page={state.pagination.page}
|
|
@@ -352,6 +658,7 @@ export default defineComponent({
|
|
|
v-model:pageTotal={state.pagination.pageTotal}
|
|
|
onList={getList}
|
|
|
sync
|
|
|
+ saveKey='studentDetail-evaluationRecords'
|
|
|
/>
|
|
|
</div>
|
|
|
<NModal
|
|
@@ -371,6 +678,12 @@ export default defineComponent({
|
|
|
src={reportSrc.value}></iframe>
|
|
|
</div>
|
|
|
</NModal>
|
|
|
+
|
|
|
+ <CardPreview
|
|
|
+ v-model:show={previewShow.value}
|
|
|
+ item={previewItem.value}
|
|
|
+ isDownload={false}
|
|
|
+ />
|
|
|
</>
|
|
|
);
|
|
|
}
|