能够满足大部分核心需求(标绿):报表部分应该比较难。
项目地址
前端编译 https://gitlab.com/m7840/toeic_vue_dist
Vue源码 https://gitlab.com/m7840/toeic_vue
Django源码 https://gitlab.com/m7840/toeic_python
项目架构
流程
项目效果
学员界面:前后端分离
管理员界面:前后端不分离
项目经验:
1. vue.js的坑
Django的vue.js用axios请求数据,只适用于Django为API数据接口;不适用于再访问Django以外的数据接口,访问Django以外的数据接口会遇到跨域(百度无法解决)。最后我采用前后端分离。文章来源:https://www.toymoban.com/news/detail-621321.html
2. session.storage是非响应式数据,需要reload来刷新网页。
3.前后端分离才是Django项目首选,因为数据来源一般是其他网页的API。
4. JS还是不熟悉
项目重构:
将session.storage改成Vuex(Vuex三连要写完,否则会报错)
文章来源地址https://www.toymoban.com/news/detail-621321.html
<template>
<el-row>
<el-col :span="24" v-for="(o, index) in 1" :key="o" :offset="index > 0 ? 2 : 0">
<div class="container" v-loading="loading">
<div class="row py-5">
<div id="pnl1View">
<div style="line-height: 30px;">
{{ remark }}
</div>
<div style="line-height: 30px;">
你好,英文成绩如下:
</div>
<div id="Content" style="width: 80%;">
<div id="Content_R">
<div>
<table class="table table-striped table-bordered" style="border-color:#31B6FD;border-width:1px;border-style:Solid;border-collapse:collapse;text-align: center">
<tbody>
<tr style="font-family:微軟正黑體,Tahoma,Arial,微軟雅黑體;font-size:15px;">
<th scope="col">Course</th>
<th align="center">英文類別</th>
<th align="center">Range</th>
<th align="center">英文標準</th>
<th align="center">最高成績</th>
<th align="center">兩年內最高成績</th>
<th scope="col">Test</th>
</tr>
<tr style="font-family:微軟正黑體,Tahoma,Arial,微軟雅黑;font-size:14px;">
<td align="center" valign="middle" rowspan="4" style="width:250px;">
<a>EN-0001.LiveABC考試</a>
</td>
<td align="center" valign="middle" rowspan="4" style="width:65px;white-space:nowrap;">{{ UserEnglishCategory.Category }}</td>
<td align="center" valign="middle" style="width:65px;white-space:nowrap;">R1</td>
<td align="center" valign="middle" style="width:65px;white-space:nowrap;">{{ UserEnglishCategory.R1_score }}</td>
<td align="center" valign="middle" rowspan="4" style="width:65px;white-space:nowrap;">{{ UserScore.highest_score }}</td>
<td class="tdbr" align="center" valign="middle" rowspan="4" style="width:65px;white-space:nowrap;">{{ UserScore.two_years_highest_score }}<br>({{ UserScore.two_years_highest_score_date }})</td>
<td align="center" valign="middle" rowspan="4" style="width:65px;white-space:nowrap;">
<input id="apply" title="点击查看详情" @click="showApplyTable" value="查看考试排程" class="btn btn-white border" role="button">
</td>
</tr>
<tr style="font-family:微軟正黑體,Tahoma,Arial,微軟雅黑;font-size:14px;">
<td align="center" valign="middle" style="width:65px;white-space:nowrap;">R2</td>
<td align="center" valign="middle" style="width:65px;white-space:nowrap;">{{ UserEnglishCategory.R2_score }}</td>
</tr>
<tr style="font-family:微軟正黑體,Tahoma,Arial,微軟雅黑;font-size:14px;">
<td align="center" valign="middle" style="width:65px;white-space:nowrap;">R3</td>
<td align="center" valign="middle" style="width:65px;white-space:nowrap;">{{ UserEnglishCategory.R3_score }}</td>
</tr>
<tr style="font-family:微軟正黑體,Tahoma,Arial,微軟雅黑;font-size:14px;">
<td align="center" valign="middle" style="width:65px;white-space:nowrap;">R4</td>
<td align="center" valign="middle" style="width:65px;white-space:nowrap;">{{ UserEnglishCategory.R4_score }}</td>
</tr>
</tbody>
</table>
</div><br>
</div>
<div :class="collapseClass" id="collapseExample">
<table class="table table-striped table-sm table-bordered">
<thead>
<tr align="center" valign="middle" style="color:White;background-color:#6480d3;font-family:微軟正黑體,Tahoma,Arial,微軟雅黑體;font-size:8px;">
<th scope="col">Schedule_Code</th>
<th scope="col">Start_Date</th>
<th scope="col">End_Date</th>
<th scope="col">location</th>
<th scope="col">Max Headcount</th>
<th scope="col" style="width:10%">App Num</th>
<th scope="col" style="width:20%">Apply</th>
</tr>
</thead>
<tr align="center" valign="middle" v-for="item in UserSchedule.new_schedule" style="color:Black;border-color:#E0E0E0;font-size:10px;height: 50px;">
<td>{{ item.schedule.Schedule_Code }}</td>
<td>{{ item.schedule.Start_Date }}</td>
<td>{{ item.schedule.End_Date}}</td>
<td>{{ item.schedule.location}}</td>
<td>{{ item.schedule.max_hc}}</td>
<td>{{ item.schedule.applied_hc}}</td>
<td class="p-2">
<button v-if="item.NotApplyAllowTest" class="btn btn-primary btn-outline-primary border" @click="Apply_Test(myEmployeeID,item.schedule.Schedule_Code,mydeptCode,myname,myemail)" role="button" style="color:Black;font-size:8px;"><i class="el-icon-check"></i>点击申请</button>
<button v-if="item.AppliedCancelTest" class="btn btn-danger btn-outline-danger border" @click="Cancel_Test(myEmployeeID,item.schedule.Schedule_Code,mydeptCode,myname,myemail)" role="button" style="color:Black;font-size:8px;"><i class="el-icon-delete"></i>点击取消</button>
<span v-if="item.NotApplyAllowTest || item.AppliedCancelTest"></span>
<span v-else>考场人数已满,或未达到考试时间</span>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</el-col>
</el-row>
</template>
<script>
import axios from "axios";
import { mapState } from 'vuex'
export default {
name: "MyContainer",
data() {
return {
currentDate: new Date(),
collapseClass:'collapse',
loading:false,
};
},
computed:{
...mapState({
UserScore: (state) => state.home.UserScore || '',
UserSchedule: (state) => state.home.UserSchedule,
UserEnglishCategory: (state) => state.home.EnglishCategory || '',
mydeptCode: (state) => state.home.deptid,
myname: (state) => state.home.cname,
myEmployeeID: (state) => state.home.user_decode_sub || '',
EnglishCategory: (state) => state.home.EnglishCategory,
myemail: (state) => state.home.user_decode_email,
testMsg: (state) => state.home.testMsg,
}),
remark(){
let UserScore = JSON.parse(sessionStorage.getItem('UserScore'))
if (UserScore){
return UserScore["remark"] || ''
}else{
return ''
}
}
},
mounted() {
setTimeout(() =>{
this.GetUserScoreDjango(this.myEmployeeID),
this.GetUserScheduleDjango(this.myEmployeeID)
}, 1000);
this.set_loading_to_false()
console.log('myEmployeeID123',this.myEmployeeID)
},
watch: {
UserSchedule: {
handler: function () {
console.log('UserSchedule改变了')
},
deep: true
}
},
methods: {
set_loading_to_false(){
setTimeout(() =>this.loading=false, 200);
},
showApplyTable(){
if(this.collapseClass=='collapse'){
this.collapseClass = 'false'
}else{
this.collapseClass ='collapse'
}
},
GetUserScoreDjango(emID){
// axios({
// method: "GET",
// url: "/api/api_user_score/" + emID,
// }).then(res => {
// console.log('GetUserScoreDjango',res);
// sessionStorage.setItem('UserScore',JSON.stringify(res.data))
// }).catch(error => {
// console.log('GetUserScoreDjango',error);
// })
this.$store.dispatch("getUserScoreDjangoData", {
myemployeeID: emID,
});
},
GetUserScheduleDjango(emID){
//脱去""的外壳
// let employeeID = emID.replace('"', '').replace('"', '');
// axios({
// method: "GET",
// url: "/api/api_user_schedule_show/" + employeeID,
// }).then(res => {
// console.log('GetUserScheduleDjango',res);
// sessionStorage.removeItem('UserSchedule'),
// sessionStorage.setItem('UserSchedule',JSON.stringify(res.data))
// console.log('UserSchedule',this.UserSchedule)
// }).catch(error => {
// console.log('GetUserScheduleDjango',error);
// })
this.$store.dispatch("getUserScheduleDjangoData", {
myemployeeID: emID,
});
},
Apply_Test(myemployeeID,mySchedule_Code,mydeptCode,myname,myemail,){
// //脱去""的外壳
// let employeeID = myemployeeID.replace('"', '').replace('"', '');
// let Schedule_Code = mySchedule_Code.replace('"', '').replace('"', '');
// let deptCode = mydeptCode.replace('"', '').replace('"', '');
// let name = myname.replace('"', '').replace('"', '');
// // let Test_Msg = ''
// let email = myemail.replace('"', '').replace('"', '');
this.loading=true;
// axios({
// method: "GET",
// url: "/api/api_test_apply/" + employeeID + '/' + Schedule_Code + '/' + deptCode + '/' + name + '/' + email + '/',
// }).then(res => {
// console.log('Apply_Test',res);
// this.GetUserScheduleDjango(employeeID)
// this.loading=false
// alert('报名成功')
// }).catch(error => {
// console.log('Apply_Test',error);
// this.loading=false
// alert('报名失败,请查看考场人数或考试日期间隔')
// })
// this.$store.dispatch("getApplyTest", {
// myemployeeID : myemployeeID,
// mySchedule_Code : mySchedule_Code,
// mydeptCode : mydeptCode,
// myname : myname,
// myemail : myemail,
// })
// this.GetUserScheduleDjango(myemployeeID)
// this.loading=false;
// alert('报名成功')
try {
this.$store.dispatch("getApplyTest", {
myemployeeID : myemployeeID,
mySchedule_Code : mySchedule_Code,
mydeptCode : mydeptCode,
myname : myname,
myemail : myemail,
})
setTimeout(() => {
this.GetUserScheduleDjango(myemployeeID)
}, 3000);
setTimeout(() => {
this.loading=false;
console.log('testMsg',this.testMsg)
if(this.testMsg.apply_result[0]==='申请成功'){
alert('报名成功')
}else{
alert('报名失败,请查看考场人数或考试日期间隔')
}
}, 4000);
} catch (error) {
console.log('Apply_Test',error);
this.loading=false;
}
},
Cancel_Test(myemployeeID,mySchedule_Code,mydeptCode,myname,myemail){
// //脱去""的外壳
// let employeeID = myemployeeID.replace('"', '').replace('"', '');
// let Schedule_Code = mySchedule_Code.replace('"', '').replace('"', '');
// let deptCode = mydeptCode.replace('"', '').replace('"', '');
// let name = myname.replace('"', '').replace('"', '');
// // let Test_Msg = ''
// let email = myemail.replace('"', '').replace('"', '');
this.loading=true;
// axios({
// method: "GET",
// url: "/api/api_test_cancel/" + employeeID + '/' + Schedule_Code + '/'+ deptCode + '/' + name + '/' + email + '/',
// }).then(res => {
// console.log('Cancel_Test',res);
// // Test_Msg = JSON.stringify(res.data)
// // sessionStorage.setItem('Test_Msg',Test_Msg)
// this.GetUserScheduleDjango(employeeID)
// this.loading=false
// alert('取消成功')
// }).catch(error => {
// console.log('Cancel_Test',error);
// this.loading=false
// alert('取消失败')
// })
try {
this.$store.dispatch("getCancelTest", {
myemployeeID : myemployeeID,
mySchedule_Code : mySchedule_Code,
mydeptCode : mydeptCode,
myname : myname,
myemail : myemail,
})
setTimeout(() => {
this.GetUserScheduleDjango(myemployeeID)
}, 3000);
setTimeout(() => {
this.loading=false;
console.log('testMsg',this.testMsg)
if(this.testMsg.apply_result[0]==='取消成功'){
alert('取消成功')
}else{
alert('取消失败')
}
}, 4000);
} catch (error) {
console.log('Apply_Test',error);
this.loading=false;
}
},
},
};
</script>
<style scoped>
.time {
font-size: 13px;
color: #999;
}
.bottom {
margin-top: 13px;
line-height: 12px;
}
.button {
float: right;
color: #999999;
}
.image {
width: 100%;
display: block;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both;
}
</style>
到了这里,关于【Django+Vue】英文成绩管理平台--20230727的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!