2026-05-11 15:15:28 +08:00

481 lines
12 KiB
Vue

<script setup lang="ts">
import LoadIcon from '@/page/system/mailbox/components/LoadIcon.vue'
import dayjs from 'dayjs'
import { useRouter } from 'vue-router'
import { $XXL } from '@/utils'
import homeworkApi, { type PaperRecord, type SubjectPaperRecord } from '@/api/subject/homework'
import { resource_type_homework } from '@/page/subject/doWork'
defineOptions({
name: 'Homework',
})
const router = useRouter()
const OSS_URL = import.meta.env.VITE_OSS_URL
// 作业科目列表
const subjectList = ref([] as any[])
// 所有的作业记录
const subjectPaperMap = ref(new Map<string, SubjectPaperRecord>())
// 当前选中的科目
const activeSubjectId = ref('')
watch(
() => activeSubjectId.value,
newVal => {
if (!newVal) return
paperList.value = subjectPaperMap.value.get(newVal)?.records || []
curPaper.value = paperList.value[0] || {}
},
)
// 作业列表
const paperList = ref([] as PaperRecord[])
const listLoading = ref(false)
const bookSidebarRef = ref()
// 当前作业
const curPaper = ref({} as PaperRecord)
function handleSelectPaper(item: PaperRecord) {
curPaper.value = item
}
const pageLoading = ref(false)
const pageError = ref(false)
onMounted(async () => {
pageLoading.value = true
listLoading.value = true
$XXL.setScreenOn(1)
try {
subjectPaperMap.value = await homeworkApi.getUnfinishedHomework()
// 学科
const subjects = [] as any[]
subjectPaperMap.value.forEach(item => {
subjects.push({
id: item.subjectId,
name: item.subjectName,
warning: true,
})
})
subjectList.value = subjects
// 选中的学科
activeSubjectId.value = subjectList.value[0].id
// console.log('----',subjectList.value)
} catch {
pageError.value = true
} finally {
pageLoading.value = false
listLoading.value = false
}
})
// 每次进入页面,都刷新数据
onBeforeMount(() => {
listLoading.value = true
})
function to(url: string) {
router.push(url)
}
// 开始答题
const startDoWork = () => {
router.push({
path: '/subject/doWork',
query: {
resourceType: resource_type_homework,
recordId: curPaper.value.id,
reportFlag: 0,
subjectId: activeSubjectId.value,
},
})
}
</script>
<template>
<div class="uncomplete">
<div
class="book"
:style="{
'background-image': `url(${OSS_URL}/urm/book_bg.svg)`,
}"
>
<template v-if="paperList.length">
<div class="book-sidebar-box">
<div class="book-sidebar hidden_scroll">
<div ref="bookSidebarRef" class="scroll-box">
<div
v-for="i in paperList"
:key="i.id"
:class="{
'book-sidebar-item': true,
pointer: true,
active: curPaper.id === i.id,
}"
:style="{
'background-image':
curPaper.id === i.id
? `url(${OSS_URL}/urm/mailbox_sidebar_active_bg.svg)`
: `url(${OSS_URL}/urm/mailbox_sidebar_bg.svg)`,
}"
@click="handleSelectPaper(i)"
>
<Icon
:name="curPaper.id === i.id ? 'homeWork_job-item-active' : 'homeWork_job-item'"
class="icon"
width="84"
></Icon>
<div class="info">
<div class="info-title">{{ i.paperName }}</div>
<div class="info-time">
{{ dayjs(i.createTime).format('YYYY/MM/DD&nbsp;&nbsp;&nbsp;HH:mm') }}
</div>
</div>
</div>
</div>
</div>
<LoadIcon v-if="listLoading" style="margin-top: 0"></LoadIcon>
</div>
<div class="book-main">
<div class="info flex-end">
<div class="info-title">{{ curPaper.paperName }}</div>
<div class="info-time">
开始日期:
{{ dayjs(curPaper.startTime).format('YYYY/MM/DD&nbsp;&nbsp;&nbsp;HH:mm') }}
</div>
</div>
<div class="info center">
<div class="info-name">
<span style="color: #999">来自:</span>{{ curPaper.publisherName }}
</div>
<div class="info-time">
截止日期:
{{ dayjs(curPaper.endTime).format('YYYY/MM/DD&nbsp;&nbsp;&nbsp;HH:mm') }}
</div>
</div>
<div class="content">{{ curPaper.remark }}</div>
<div class="tab">
<div
class="tab-icon"
:style="{
'background-image': `url(${OSS_URL}/urm/homeWork/tab.svg)`,
}"
>
<Icon class="icon" name="homeWork_paper" width="32"></Icon>
试卷
</div>
</div>
<div class="content paper">{{ curPaper.paperName }}</div>
<div class="btn-box">
<mj-button
width="386"
height="108"
size="48"
:type="curPaper.costTime ? 'success' : 'primary'"
@click="startDoWork"
>
{{ curPaper.costTime ? '继续答题' : '开始答题' }}
</mj-button>
</div>
</div>
</template>
<Empty
v-else
class="empty"
:type="listLoading ? 'loading' : 'task'"
content="还没有作业哦~"
></Empty>
</div>
<div class="top">
<BackBar leftText="作业" />
<div class="top-history">
<!-- <mj-button type="success" tilt @click="to(`/system/homeWork/statistics`)"
>统计分析</mj-button
> -->
<!-- <mj-button
type="success"
tilt
@click="to(`/system/homeWork/wrong?subjectId=${activeSubjectId}`)"
>错题本</mj-button
> -->
<mj-button type="success" tilt @click="to(`/system/homeWork/wrongQuestion`)">
错题本
</mj-button>
<Icon
name="homeWork_hisJob"
width="120"
class="pointer"
@click="to(`/system/homeWork/history`)"
></Icon>
</div>
</div>
<div v-if="subjectList.length" class="main">
<div class="main-sidebar">
<Sidebar v-model="activeSubjectId" :config="subjectList"></Sidebar>
</div>
</div>
<Empty
v-else
class="empty"
:type="pageLoading ? 'loading' : 'task'"
content="还没有作业哦~"
></Empty>
</div>
</template>
<style scoped lang="scss">
.uncomplete {
height: 100vh;
overflow: hidden;
box-sizing: border-box;
position: relative;
background-repeat: no-repeat;
background-size: cover;
background-color: $theme-color-bg;
.book {
box-sizing: border-box;
position: fixed;
width: 133.5vh;
height: 94vh;
left: 300px;
top: 6.67vh;
background-repeat: no-repeat;
background-position: top left;
background-size: 100% 100%;
padding: 10vh 11.67vh 6.33vh 9vh;
display: flex;
z-index: 2;
&-sidebar {
width: 36.67vh;
height: 100%;
flex-shrink: 0;
&-item {
padding: 0.83vh;
display: flex;
height: 9.67vh;
flex-shrink: 0;
margin-bottom: 1.33vh;
background-color: #fff;
box-shadow: 0 0.33vh 0.17vh 0 rgba(0, 0, 0, 0.15);
background-repeat: no-repeat;
background-position: 26.17vh center;
background-size: 11.17vh, 13vh;
border: 0.5vh solid transparent;
&.unready {
background-color: #dcdff5;
}
&.active {
background-color: #fff;
border-color: rgb(255, 240, 31);
// background-position:
// center,
// 314px center;
// background-size: 100%, 134px, 156px;
}
&:last-child {
margin-bottom: 0;
}
.icon {
width: 7vh;
height: 7vh;
flex-shrink: 0;
background: #1c2a3a;
margin-right: 1.33vh;
border-radius: 50%;
}
.info {
width: calc(100% - 8.33vh);
&-title {
color: $font-color;
font-family: $font-text;
font-size: 2.67vh;
font-style: normal;
font-weight: 400;
line-height: 4vh; /* 150% */
@include single_ellipsis;
}
&-time {
font-size: 2vh;
}
}
}
}
&-main {
margin-left: 5.83vh;
padding-top: 1.33vh;
width: calc(100% - 3.33vh);
.info {
padding: 1.33vh 0;
display: flex;
justify-content: space-between;
&.flex-end {
align-items: end;
border-bottom: 0.17vh solid rgba(0, 0, 0, 0.45);
}
&.center {
align-items: center;
border-bottom: 0.08vh solid rgba(0, 0, 0, 0.45);
}
&-title {
color: $font-color;
font-family: $font-special;
font-size: 2.67vh;
font-style: normal;
font-weight: 400;
line-height: 1.5;
width: 41.67vh;
margin-right: 1vh;
@include single_ellipsis;
}
&-name {
color: #999;
font-family: 'PingFang SC';
font-size: 2.67vh;
font-style: normal;
font-weight: 400;
line-height: 1.2;
// width: calc(100% - 400px);
width: 41.67vh;
margin-right: 1vh;
@include single_ellipsis;
}
&-time {
font-size: 2vh;
line-height: 3vh; /* 150% */
@include single_ellipsis;
}
}
.content {
color: #333;
font-family: $font-text;
font-size: 2.67vh;
font-style: normal;
font-weight: 400;
line-height: 4vh; /* 150% */
margin: 2.67vh 0;
text-indent: 2em;
height: 20vh;
// @include multiple_ellipsis(5);
@include hidden_scroll;
&.paper {
height: 8vh;
@include multiple_ellipsis(2);
}
}
.tab {
// padding-top: 32px;
&-icon {
box-sizing: border-box;
width: 19vh;
height: 4.33vh;
background-position: top left;
background-repeat: no-repeat;
background-size: 100%;
padding: 0.17vh 0 0.17vh 4.67vh;
color: $font-color;
font-family: 'PingFang SC';
font-size: 2.67vh;
font-style: normal;
font-weight: 500;
line-height: 4vh; /* 150% */
display: flex;
align-items: center;
.icon {
// width: 32px;
// height: 32px;
margin-right: 1.33vh;
}
}
}
.btn-box {
box-sizing: border-box;
padding-top: 1.33vh;
display: flex;
justify-content: flex-end;
.x-button {
font-family: $font-text;
}
}
.btn {
box-sizing: border-box;
padding-top: 1.5vh;
width: 32.17vh;
height: 9vh;
flex-shrink: 0;
border-radius: 5vh;
background-size: 100%;
box-shadow: 0 0.5vh 0.17vh 0 rgba(0, 0, 0, 0.25);
text-align: center;
color: $font-color;
text-align: center;
font-family: $font-text;
font-size: 4vh;
font-style: normal;
font-weight: 400;
line-height: 6vh; /* 150% */
}
}
.empty {
height: 100%;
}
}
.top {
padding: 3vh 5.33vh 0;
}
.top-history {
z-index: 2;
position: absolute;
top: 1.67vh;
right: 64px;
display: flex;
align-items: center;
.mj-button {
margin: 0 16px 0.67vh;
font-family: $font-text;
}
.x-icon {
margin-left: 16px;
}
}
.main {
height: calc(100% - 13vh);
padding-left: 64px;
padding-right: 20px;
position: relative;
&-sidebar {
position: absolute;
left: 64px;
top: 1vh;
height: calc(100% - 2.5vh);
width: 22.92vh;
}
}
.empty {
height: calc(100% - 25vh);
}
}
.info-time {
color: #999;
font-family: 'PingFang SC';
font-size: 1.67vh;
font-style: normal;
font-weight: 400;
line-height: 2.5vh; /* 150% */
margin-top: 0.5vh;
span {
margin-right: 24px;
}
}
</style>