File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<div>
<!-- <Side_t></Side_t> -->
<div style="padding: 15px 60px 120px 60px">
<div class="flex justify-between align-center">
<div class="logo mb25"><img src="../../../resources/img/logo2.png" alt="" /></div>
<Header></Header>
</div>
<div class="main-wrap flex justify-between">
<div class="gd-2">
<div class="mb30">
<div>
<img src="../../../resources/img/img16_s.png" alt="" />
<div class="mt10" style="width: 100%">
<p class="name mb10">{{ studentInfo.studentName }}</p>
<p class="mb5">
{{ studentInfo.institutionName }} {{ studentInfo.grade }}학년
{{ studentInfo.className }}
</p>
<!-- <progress-bar :progress="progress"></progress-bar> -->
<div class="problem-box mt25">
<p style="font-weight: bold">
지금까지 푼 총 문제 수 :
<span style="color: #9528b7; font-size: 16px; font-weight: bold"
>{{ studentInfo.totalProblemsSolved }}개</span
>
</p>
</div>
</div>
</div>
<hr />
<div class="history-box">
<p class="title2 mb25">최근 학습 히스토리</p>
<ul class="flex justify-between">
<li v-for="historyItem in studentInfo.history" :key="historyItem.unitId">
[{{ historyItem.bookName }}] {{ historyItem.unitName }}
</li>
</ul>
</div>
<hr />
<div class="title-box flex justify-between mb20">
<p class="name">{{ studentInfo.studentName }}학생 랭킹</p>
</div>
<div class="mypage mb30">
<div class="flex-column" style="gap: 20px">
<div class="textbook book-red">
<div class="text">
<p class="title1" style="color: #fff">포토북 랭킹</p>
</div>
<div class="box">
<P class="title2 mt10"
>현재 {{ stdCount }}명 중 <em class="red">{{ photo_rank }}등</em>입니다.</P
>
</div>
</div>
<div class="textbook">
<div class="text">
<p class="title1" style="color: #fff">진도율 랭킹</p>
</div>
<div class="box">
<P class="title2 mt10"
>현재 {{ stdCount }}명 중
<em class="yellow">{{ problem_rank }}등</em>입니다.</P
>
</div>
</div>
<div class="textbook book-blue">
<div class="text">
<p class="title1" style="color: #fff">점수 랭킹</p>
</div>
<div class="box">
<P class="title2 mt10"
>현재 {{ stdCount }}명 중 <em class="blue">{{ score_rank }}등</em>입니다.</P
>
</div>
</div>
<div class="textbook book-navy">
<div class="text">
<p class="title1" style="color: #fff">학습시간 랭킹</p>
</div>
<div class="box">
<P class="title2 mt10"
>현재 {{ stdCount }}명 중 <em class="navy">{{ time_rank }}등</em>입니다.</P
>
</div>
</div>
</div>
</div>
<hr />
<div>
<div class="title-box flex justify-between mb20">
<p class="title">사진첩</p>
</div>
<div class="photobook">
<div class="flex justify-between">
<div class="box" style="gap: 5px">
<div><img src="../../../resources/img/img198_12p.png" alt="" /></div>
</div>
<div class="text mt10">
<p class="title1 mb10">{{ studentInfo.studentName }}의 사진첩</p>
<button
@click="goToPage('PhotoBook')"
type="button"
title="글쓰기"
class="new-btn"
>
바로가기
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="gd-9 flex-column" style="flex: 1">
<div class="title-box flex justify-between mb40">
<p class="title">전체 진행률</p>
</div>
<div class="flex">
<div class="wrap" style="flex: 1">
<p class="name">학습 현황</p>
<div class="flex justify-center">
<Dounutchart />
</div>
<div class="textbox">
<p class="title2">오늘의 학습현황</p>
<!-- 안전하게 진도율을 소수점 한자리 수까지 표시 -->
<p class="name">
{{
donutChartData.clearUnitNum && donutChartData.totalScheduleUnitNum
? (
(donutChartData.clearUnitNum / donutChartData.totalScheduleUnitNum) *
100
).toFixed(1)
: 0
}}
%
</p>
</div>
<p class="title2">학습시간</p>
<p class="name">학습시간 n시간</p>
</div>
<div class="wrap" style="flex: 1">
<p class="name">이해/표현 점수</p>
<div class="flex justify-center mt50">
<ColumnLineChart />
</div>
</div>
</div>
<div class="wrap" style="flex: 2">
<p class="name">교재별 진행률</p>
<div class="flex justify-center">
<StackedBarChart />
</div>
</div>
<div class="flex">
<div class="wrap" style="flex: 1">
<p class="name">오늘의 학습 일정</p>
<div
class="scheduleBox mt20"
style="gap: 20px"
v-for="(schedule, index) in schedules"
:key="index"
>
<div class="flex justify-between align-center" style="gap: 70px">
<div><img src="../../../resources/img/img217_22s.png" alt="" /></div>
<div
class="wrap cs-pt"
:class="{ 'cs-pt-clicked': isClicked }"
@click="toggleClicked"
style="width: 100%"
>
<div class="text-lf flex justify-between align-center">
<div>
<div class="flex align-center mb10" style="gap: 10px">
<p class="title2">
<em class="gray-bd">{{ schedule.schdl_unit }}교시</em>
</p>
<p class="title1">{{ schedule.schedule_time }}</p>
</div>
<div class="title-box mb10">
<span class="title">{{ schedule.unit_nm }}</span>
</div>
<p class="title2">{{ schedule.book_nm }}</p>
</div>
<div class="">
<img src="../../../resources/img/img214_19s.png" alt="" />
</div>
</div>
</div>
</div>
</div>
</div>
<div class="flex-column" style="flex: 1">
<div class="wrap">
<p class="name">교재별 오답률</p>
<div class="flex justify-center">
<Barchart />
</div>
</div>
<div class="wrap">
<p class="name">문제 카테고리별 세부 점수</p>
<div class="flex justify-center">
<CategoryBarChart />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Header from '../../layout/Header.vue';
import Menu from '../../layout/Menu.vue';
import Side_t from '../../layout/Side_t.vue';
import ProgressBar from '../../component/ProgressBar.vue';
import StackedBarChart from './StackedBarChart.vue';
import Barchart from './Barchart.vue';
// import Bubblechart from './Bubblechart.vue';
import CategoryBarChart from './CategoryBarChart.vue';
import Dounutchart from './Dounutchart.vue';
import ColumnLineChart from './ColumnLineChart.vue';
import axios from 'axios';
export default {
data() {
return {
stdCount: 0,
photo_rank: 0,
problem_rank: 0,
score_rank: 0,
time_rank: 0,
progress: 20,
donutChartData: {},
currentDate: '2024-10-25',
studentInfo: {
studentName: '',
institutionName: '',
grade: '',
className: '',
studentQuestion: '',
history: [],
},
currentStdId: 'USID_000000000000002',
schedules: [],
timeList: [
{ label: '1교시', time: '08:00 ~ 09:00', value: '1' },
{ label: '2교시', time: '09:00 ~ 10:00', value: '2' },
{ label: '3교시', time: '10:00 ~ 11:00', value: '3' },
{ label: '4교시', time: '11:00 ~ 12:00', value: '4' },
{ label: '5교시', time: '13:00 ~ 14:00', value: '5' },
{ label: '6교시', time: '14:00 ~ 15:00', value: '6' },
],
};
},
methods: {
goToPage(page) {
this.$router.push({ name: page });
},
classStdCount: function () {
const vm = this;
axios({
url: '/userclass/classStdCountByUserId.json',
method: 'post',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
data: {
userId: 'USID_000000000000002', // 로그인한 학생의 userId
},
})
.then(function (response) {
console.log('classStdCount - response : ', response.data);
vm.stdCount = response.data;
})
.catch(function (error) {
console.log('classStdCount - error : ', error);
alert('반 학생 수 조회에 오류가 발생했습니다.');
});
},
photoRankByLikeData: function () {
const vm = this;
axios({
url: '/photo/photoRankByLikeData.json',
method: 'post',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
data: {
sclsId: '1',
stdId: '1',
},
})
.then(function (response) {
console.log('Photo Rank - response : ', response.data);
vm.photo_rank = response.data;
})
.catch(function (error) {
console.log('Photo Rank - error : ', error);
alert('학생 사진 랭킹 조회에 오류가 발생했습니다.');
});
},
getUserRankByScore: function () {
const vm = this;
axios({
url: '/userclass/getUserRankByScore.json',
method: 'post',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
data: {
userId: 'USID_000000000000002', // 로그인한 학생의 userId
},
})
.then(function (response) {
console.log('User Rank - response : ', response.data);
vm.score_rank = response.data;
})
.catch(function (error) {
console.log('User Rank - error : ', error);
alert('점수 랭킹 조회에 오류가 발생했습니다.');
});
},
getUserRankByStudyTime: function () {
const vm = this;
axios({
url: '/userclass/getUserRankByStudyTime.json',
method: 'post',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
data: {
userId: '1', // 로그인한 학생의 userId
},
})
.then(function (response) {
console.log('User Rank - response : ', response.data);
vm.time_rank = response.data;
})
.catch(function (error) {
console.log('User Rank - error : ', error);
alert('학습시간 랭킹 조회에 오류가 발생했습니다.');
});
},
problemRankByProblemData: function () {
const vm = this;
axios({
url: '/problemLog/problemRankByProblemData.json',
method: 'post',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
data: {
sclsId: '1',
stdId: '2',
},
})
.then(function (response) {
console.log('Problem Rank - response : ', response.data);
vm.problem_rank = response.data;
})
.catch(function (error) {
console.log('Problem Rank - error : ', error);
alert('학생 문제 랭킹 조회에 오류가 발생했습니다.');
});
},
// 학생 데이터 가져오기
fetchStudentInfo() {
axios
.post('/studentInfo/getInfo.json', { userId: this.currentStdId })
.then((response) => {
console.log(response.data);
this.studentInfo = response.data;
})
.catch((error) => {
console.error('학생 정보 가져오기 실패:', error);
});
},
// 현재 날짜의 학생 학습률 데이터 가져오기
getStdProgressData() {
const vm = this;
axios
.post('/dashboard/stdProgressData.json', {
std_id: vm.currentStdId,
current_date: vm.currentDate,
})
.then((response) => {
vm.donutChartData = response.data;
console.log(vm.donutChartData);
})
.catch((error) => {
console.error('오늘의 학생 학습 현황 데이터를 가져오는 중 오류 발생:', error);
});
},
// 현재학생의 학습 스케줄 가져오기
fetchSchedules() {
axios
.post(
'/schedule/selectSchedule.json',
{ stdId: '2' },
{
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
}
)
.then((response) => {
this.schedules = response.data.map((schedule) => {
const matchingTime = this.timeList.find((time) => time.value === schedule.schdl_unit);
return {
...schedule,
schedule_time: matchingTime ? matchingTime.time : '시간 정보 없음',
};
});
console.log(this.schedules);
})
.catch((error) => {
console.error('fetchUnits - error:', error);
alert('단원 목록을 불러오는 중 오류가 발생했습니다.');
});
},
},
watch: {},
computed: {},
components: {
Header: Header,
Menu: Menu,
// Footer:Footer,
Side_t: Side_t,
ProgressBar,
StackedBarChart: StackedBarChart,
Barchart: Barchart,
// Bubblechart: Bubblechart,
CategoryBarChart,
Dounutchart: Dounutchart,
ColumnLineChart: ColumnLineChart,
},
mounted() {
this.getStdProgressData();
this.fetchStudentInfo();
this.classStdCount();
this.photoRankByLikeData();
this.getUserRankByScore();
this.problemRankByProblemData();
this.getUserRankByStudyTime();
this.fetchSchedules();
},
};
</script>
<style scoped>
.main-wrap {
margin-top: 20px;
position: static;
width: 100%;
height: 100%;
}
.history-box {
background-color: white;
padding: 30px 20px;
border: 1px solid #c6c6c6;
border-radius: 10px;
}
.history-box li {
background-color: #eaedf4;
border-radius: 10px;
font-size: 18px;
list-style-type: none;
padding: 10px;
width: 100%;
}
.problem-box {
display: flex;
align-items: center;
justify-content: center;
border: 2px solid #6327b9;
background-color: #f0eaf8;
border-radius: 8px;
padding: 10px 10px;
}
.scheduleBox {
display: flex;
flex-direction: column;
}
</style>