Commit 2ee077a3 authored by 赵炳峰's avatar 赵炳峰

master

parent 589edda8
Pipeline #448 failed with stages
<template>
<div class="data-empty">
<div class="wrapper">
<img src="@/assets/images/empty.png" alt="" />
<p>{{content }}</p>
</div>
</div>
</template>
<script>
export default {
name: 'Empty',
props: {
content: {
type: String,
default: '暂无数据'
}
}
}
</script>
<style lang="stylus" scoped>
.data-empty
height 100%
background-color #fff
display flex
justify-content center
padding-top 100px
.wrapper
text-align center
img
width 100px
height 82px
p
margin-bottom 0
text-align center
</style>
<template>
<div class="first-name">
<div class="view-label" @click="showSortDialog = true">
{{sortText}}
</div>
<div class="view-scroll">
<div class="swiper-container">
<div class="swiper-wrapper">
<div
class="swiper-slide"
:class="currentFirstName === item ? 'active' : ''"
v-for="(item, index) of firstName"
:key="`item_first_name_${index}`"
@click="handleFirstNameClick(item)"
>
<a href="javascript:;">{{ item }}</a>
</div>
</div>
</div>
</div>
<div class="collapse">
<a href="javascript:;" @click="collapse = !collapse"><i class="iconfont">&#xe113;</i></a>
</div>
<div class="surname_wrapper" v-show="collapse">
<div class="flex hd" @click="collapse = !collapse">
<div class="flex-1 lable">全部姓氏</div>
<div class="collapse">
<a href="javascript:;" ><i class="iconfont">&#xe114;</i></a>
</div>
</div>
<div class="bd">
<ul class="surname-list flex flex-wrap">
<li
class="item"
v-for="(item, index) of firstName"
:key="`item_first_name_${index}`"
>
<a
href="javascript:;"
:class="currentFirstName === item ? 'active' : ''"
@click="handleFirstNameClick(item),collapse = false">{{ item }}</a>
</li>
</ul>
</div>
</div>
<!-- 成绩情况 -->
<div v-transfer-dom>
<x-dialog :show.sync="showSortDialog">
<div class="dialog-content">
<form class="input-group">
<div class="input-row radio left" v-for="(item, index) of sorts" :key="`sort_item_${index}`" :class="disableGrade && item.value == 3 ? 'disabled' : ''">
<label :for="`sort_label_${index}`">{{item.name}}</label>
<input name="sort" type="radio" :id="`sort_label_${index}`" :checked="item.value === current" :disabled="disableGrade && item.value == 3" @change="handleSortChange(item.value)">
</div>
</form>
</div>
<div class="dialog-footer">
<a href="javascript:;" class="dialog-btn confirm" @click="showSortDialog = false">
关闭
</a>
</div>
</x-dialog>
</div>
</div>
</template>
<script>
import { TransferDom, XDialog } from 'vux'
import Swiper from 'swiper'
export default {
name: 'FirstName',
directives: {
TransferDom
},
components: {
XDialog
},
props: ['disableGrade', 'firstName'],
data () {
return {
firstNameSwiper: null,
showSortDialog: false,
sorts: [{
value: 1,
name: '按姓名排序'
}, {
value: 2,
name: '按学号排序'
}, {
value: 3,
name: '按成绩排序'
}],
current: 1,
currentFirstName: '',
collapse: false
}
},
computed: {
sortText () {
return this.current === 1 ? '姓名' : (this.current === 2 ? '学号' : '成绩')
}
},
watch: {
firstName (newValue, oldValue) {
this.$nextTick(() => {
this.firstNameSwiper = new Swiper('.swiper-container', {
freeMode: true,
freeModeMomentumRatio: 0.5,
slidesPerView: 'auto',
resistanceRatio: 0
})
})
}
},
methods: {
handleSortChange (value) {
this.current = value
this.showSortDialog = false
this.$emit('changeSort', value)
},
// 点击姓名
handleFirstNameClick (item) {
this.currentFirstName = item === this.currentFirstName ? '' : item
this.$emit('changeName', this.currentFirstName)
}
}
}
</script>
<style>
@import 'swiper/dist/css/swiper.css';
</style>
<style lang="stylus" scoped>
.first-name
position relative
height 38px
display flex
background-color #fff
&:after
content ''
position absolute
bottom 0
left 0
right 0
height 1px
transform scaleY(.5)
background-color #c8c7cc
.view-label
flex-shrink 0
line-height 38px
position relative
padding 0 10px
cursor pointer
&:after
content ''
position absolute
bottom 0
right 0
width 0
height 0
border-width: 4px
border-style solid
border-color transparent #409EFF #409EFF transparent
.view-scroll
position relative
flex 1
height 100%
overflow hidden
&:before
content ''
position absolute
top 0
left 0
bottom 0
width 5px
z-index 10
background: linear-gradient(to right,#fff,rgba(255, 255, 255, 0.3));
&:after
content ''
position absolute
top 0
right 0
bottom 0
width 5px
z-index 10
background: linear-gradient(to right,rgba(255, 255, 255, 0.3),#fff);
.swiper-container
width 100%
height 100%
.swiper-slide
width auto
padding 5px
color #333
&>a
display block
line-height 28px
padding 0 12px
color inherit
background-color #f2f2f2
&.active
color #fff
&>a
background-color #409EFF
.collapse
padding 5px
height 100%
a
display block
line-height 28px
padding 0 8px
color #fff
background-color #409EFF
.surname_wrapper
position absolute
top 0
background-color #fff
z-index 10
.hd
height 38px
align-items center
.lable
padding 0 10px
color #797979
.bd
padding 5px
.surname-list
.item
padding 5px
color #333
a
display block
line-height 28px
padding 0 12px
color inherit
background-color #f2f2f2
a.active
color #fff
background-color #409EFF
.dialog-title
position relative
padding 15px
font-size 17px
text-align left
&~.dialog-content
padding 0 15px
.dialog-content
padding 20px 15px 0
text-align left
overflow hidden
.input-group:before, .input-group:after, .input-group .input-row:after
background-color transparent
.preview
display flex
margin-bottom 10px
color #8f8f94
.view-label
flex-shrink 0
.view-content
flex 1
.dialog-footer
display flex
justify-content flex-end
padding 10px 15px
.dialog-btn
display block
line-height 36px
padding 0 8px
color #999
font-size 17px
&.confirm
color #409EFF
</style>
<template>
<div class="page-header">
<a href="javascript:;" class="prev-page icon icon-prev" @click="handlePrevClick"></a>
<div class="header-content">
<div class="page-title">
<div class="bd ellipsis">{{ pageTitle }}</div>
<a href="javascript:;" class="info-btn" @click="showExamInfoDialog = true">
<i class="icon1">&#xe831;</i>
</a>
</div>
<a href="javascript:;" class="router-btn" @click="showRouterDialog = true">
{{title}}
</a>
</div>
<!-- 考试信息 -->
<div v-transfer-dom>
<x-dialog :show.sync="showExamInfoDialog">
<div class="dialog-title">
信息
</div>
<div class="dialog-content">
<div class="preview">
<div class="view-label">
科任老师:
</div>
<div class="view-content">
{{ examInfo.teacherName }}
</div>
</div>
<div class="preview">
<div class="view-label">
录入教师:
</div>
<div class="view-content">
{{ examInfo.enterTeacher }}
</div>
</div>
<div class="preview">
<div class="view-label">
等级确定:
</div>
<div class="view-content">A>=卷面分*{{ examInfo.rankA }}%,B>=卷面分*{{ examInfo.rankB }}%,C>=卷面分*{{ examInfo.rankC }}%,D>=卷面分*{{ examInfo.rankD }}%。</div>
</div>
</div>
<div class="dialog-footer">
<a href="javascript:;" class="dialog-btn confirm" @click="showExamInfoDialog = false">
关闭
</a>
</div>
</x-dialog>
</div>
<!-- 成绩情况 -->
<div v-transfer-dom>
<x-dialog :show.sync="showRouterDialog">
<div class="dialog-content">
<form class="input-group">
<div class="input-row radio left" v-for="(item, index) of routers" :key="`router_item_${index}`">
<label :for="`router_label_${index}`">{{item.name}}</label>
<input name="router" type="radio" :id="`router_label_${index}`" :checked="item.path === current" @change="handleRouterChange(item.path)">
</div>
</form>
</div>
<div class="dialog-footer">
<a href="javascript:;" class="dialog-btn confirm" @click="showRouterDialog = false">
关闭
</a>
</div>
</x-dialog>
</div>
</div>
</template>
<script>
import { TransferDom, XDialog } from 'vux'
import qs from 'qs'
export default {
name: 'PageHeader',
props: {
pageTitle: {
type: String,
default: ''
},
title: {
type: String,
default: ''
},
routers: {
type: Array,
default: () => {}
},
current: {
type: String,
default: ''
},
examInfo: {
type: Object,
default: () => {
return {
teacherName: '',
enterTeacher: '',
rankA: '',
rankB: '',
rankC: '',
rankD: ''
}
}
}
},
directives: {
TransferDom
},
components: {
XDialog
},
watch: {
},
data () {
return {
showExamInfoDialog: false,
showRouterDialog: false,
currentRouter: this.current
}
},
methods: {
handlePrevClick () {
this.$router.go(-1)
},
handleRouterChange (path) {
// console.log(path, this.$route.params.id)
// let { examBid, classId, subjectId, recordId } = this.$route.params
// this.$router.push({ path: `${path}/${examBid}/${classId}/${subjectId}/${recordId}` })
let query = this.$route.query
this.$router.replace(`${path}?${qs.stringify(query)}`)
}
}
}
</script>
<style lang="stylus" scoped>
.page-header
position relative
height 44px
padding-left 40px
background-color #8d91ff
color #fff
box-shadow: 0 1px 6px #ccc;
.prev-page
position absolute
left 0
top 0
bottom 0
padding 10px 10px
line-height 22px
color #fff
font-size 20px
.header-content
height 44px
display flex
align-items center
justify-content space-between
padding-right 10px
.page-title
display flex
overflow hidden
line-height 44px
.info-btn
display inline-block
padding 0 8px
color #fff
.icon1
font-size 16px
.router-btn
display block
position relative
font-size 14px
color #fff
border 1px solid #fff
padding 2px 10px
&:after
content ''
position absolute
bottom 0
right 0
width 0
height 0
border-width: 4px
border-style solid
border-color transparent #fff #fff transparent
.dialog-title
position relative
padding 15px
font-size 17px
text-align left
&~.dialog-content
padding 0 15px
.dialog-content
padding 20px 15px 0
text-align left
overflow hidden
.input-group:before, .input-group:after, .input-group .input-row:after
background-color transparent
.preview
display flex
margin-bottom 10px
color #8f8f94
.view-label
flex-shrink 0
.view-content
flex 1
.dialog-footer
display flex
justify-content flex-end
padding 10px 15px
.dialog-btn
display block
line-height 36px
padding 0 8px
color #999
font-size 17px
&.confirm
color #409EFF
</style>
<template>
<div class="page-header">
<a href="javascript:;" class="prev-page icon icon-prev" @click="handlePrevClick"></a>
<div class="header-content">
<div class="page-title">
{{ pageTitle }}
<!-- {{ className }}&nbsp;{{ subjectName || '' }}&nbsp;{{ itemName }} -->
</div>
<a href="javascript:;" class="router-btn" @click="showRouterDialog = true">
{{title}}
</a>
</div>
<!-- 成绩情况 -->
<div v-transfer-dom>
<x-dialog :show.sync="showRouterDialog">
<div class="dialog-content">
<form class="input-group">
<div class="input-row radio left" v-for="(item, index) of routers" :key="`router_item_${index}`">
<label :for="`router_label_${index}`">{{item.name}}</label>
<input name="router" type="radio" :id="`router_label_${index}`" :checked="item.path === current" @change="handleRouterChange(item.path)">
</div>
</form>
</div>
<div class="dialog-footer">
<a href="javascript:;" class="dialog-btn confirm" @click="showRouterDialog = false">
关闭
</a>
</div>
</x-dialog>
</div>
</div>
</template>
<script>
import { TransferDom, XDialog } from 'vux'
import qs from 'qs'
export default {
name: 'PageHeaderEva',
props: {
title: {
type: String,
default: ''
},
routers: {
type: Array,
default: () => {}
},
current: {
type: String,
default: ''
},
pageTitle: {
type: String,
default: ''
}
// className: {
// type: String,
// default: ''
// },
// subjectName: {
// type: String,
// default: ''
// },
// itemName: {
// type: String,
// default: ''
// }
},
directives: {
TransferDom
},
components: {
XDialog
},
data () {
return {
showExamInfoDialog: false,
showRouterDialog: false,
currentRouter: this.current
}
},
methods: {
handlePrevClick () {
this.$router.go(-1)
},
handleRouterChange (path) {
// console.log(path, this.$route.params.id)
// let routerParams = this.$route.params
// console.log(routerParams)
// this.$router.push({ path: `${path}/${routerParams.itemId}/${routerParams.classId}/${routerParams.termId}/${routerParams.itemName}/${routerParams.className}/${routerParams.subjectName || ''}` })
let query = this.$route.query
this.$router.replace(`${path}?${qs.stringify(query)}`)
}
}
}
</script>
<style lang="stylus" scoped>
.page-header
position relative
height 44px
padding-left 40px
background-color #8d91ff
color #fff
box-shadow: 0 1px 6px #ccc;
.prev-page
position absolute
left 0
top 0
bottom 0
padding 10px 10px
line-height 22px
color #fff
font-size 20px
.header-content
height 44px
display flex
align-items center
justify-content space-between
padding-right 10px
.page-title
line-height 44px
max-width 215px
white-space nowrap
overflow hidden
text-overflow ellipsis
.info-btn
display inline-block
padding 0 8px
color #fff
.icon1
font-size 16px
.router-btn
display block
position relative
font-size 14px
color #fff
border 1px solid #fff
padding 2px 10px
&:after
content ''
position absolute
bottom 0
right 0
width 0
height 0
border-width: 4px
border-style solid
border-color transparent #fff #fff transparent
.dialog-title
position relative
padding 15px
font-size 17px
text-align left
&~.dialog-content
padding 0 15px
.dialog-content
padding 20px 15px 0
text-align left
overflow hidden
.input-group:before, .input-group:after, .input-group .input-row:after
background-color transparent
.preview
display flex
margin-bottom 10px
color #8f8f94
.view-label
flex-shrink 0
.view-content
flex 1
.dialog-footer
display flex
justify-content flex-end
padding 10px 15px
.dialog-btn
display block
line-height 36px
padding 0 8px
color #999
font-size 17px
&.confirm
color #409EFF
</style>
<template>
<div class="panel">
<div class="segmented-control">
<router-link
class="control-item"
v-for="(item, index) of tabList"
:key="`tab_item_${index}`"
:to="`${item.path}`"
replace>
{{ item.name }}
</router-link>
<!-- :to="`${item.path}/${termId}`" -->
</div>
</div>
</template>
<script>
export default {
name: 'RouterTab',
props: {
tabList: {
type: Array,
default: () => []
}
// termId: {
// type: String,
// default: ''
// }
}
}
</script>
<style lang="stylus" scoped>
.panel
flex-shrink 0
padding 10px 15px
background-color #fff
.router-link-active
color #fff !important
background-color #007aff
</style>
<template>
<div class="container">
<v-header :title="title"></v-header>
<router-tab :tab-list="tabList" ></router-tab>
<v-search
ref="search"
:search-text="searchText"
:show.sync="showSearch"
:data="filterData"
:init.sync="filterInit"
:is-exam="isExam"
@search="handleSearchClick"
>
</v-search>
<div class="content" ref="contentWrapper">
<div>
<router-view v-if="recordData.length" :data="recordData" :is-exam="isExam" :term-id="filterInit.termId" :current-term-id="currentTermId"></router-view>
<empty v-else></empty>
</div>
</div>
</div>
</template>
<script>
import { removeRepeatByKey } from '@/assets/utils/util.js'
import BScroll from 'better-scroll'
import { showToast } from '@/assets/utils/message.js'
export default {
name: 'Index',
components: {
VHeader: () => import('@/common/header/VHeader'),
RouterTab: () => import('./../RouterTab'),
VSearch: () => import('./components/VSearch'),
Empty: () => import('@/common/Empty')
},
mixins: [],
data () {
return {
title: '考试/评价录入',
scroll: null,
tabList: [
{
name: '考试录入',
path: '/education/SQESystem/enter/exam'
},
{
name: '评价录入',
path: '/education/SQESystem/enter/evaluation'
}
],
showSearch: false,
searchText: '',
isExam: true, // 是否是考试
filterData: {
termList: [],
classList: []
},
filterInit: {
termId: [],
states: 10, // 0:未录入,1:完成,2:录入中 10 全部
classId: ['all']
},
allEvalItems: [],
recordData: [],
currentTermId: ''
}
},
watch: {},
filters: {},
created () {
this.getTermList()
},
mounted () {
this.$nextTick(() => {
this.scroll = new BScroll(this.$refs.contentWrapper, {
click: true
})
})
},
beforeRouteEnter (to, from, next) {
next(vm => { vm.isExam = to.name === 'SQESystemEnterExam' })
},
beforeRouteUpdate (to, from, next) {
this.isExam = to.name === 'SQESystemEnterExam'
this.recordData = []
to.name === 'SQESystemEnterExam' ? this.getMyExamEntryList() : this.getMyEvalEntryList()
next()
},
methods: {
getTermList () {
this.$api.SQEEvalApi.getTermList().then(res => {
let data = res.data
if (data.Status) {
let currentTerm = data.Data.filter(item => item.Enabled === 1)
this.filterData.termList = data.Data.map(item => ({ name: item.TeamName, value: item.ID }))
this.currentTermId = currentTerm[0].ID
this.filterInit.termId = [currentTerm[0].ID]
this.$route.name === 'SQESystemEnterExam' ? this.getMyExamEntryList() : this.getMyEvalEntryList()
} else {
showToast({ text: data.ResponseError.LongMessage, type: 'warn' })
}
})
},
// 获取考试录入列表
getMyExamEntryList () {
let { termId, states } = this.filterInit
this.$api.SQEExamApi.getMyExamEntryList({
term_id: termId[0],
exam_id: '',
subject_id: '',
states
}).then(res => {
let data = res.data
if (data.Status) {
this.recordData = data.Data
this.$nextTick(() => {
this.searchText = `${this.$refs['search'].$refs['termPicker'].getNameValues()}-${this.getStateText()}`
})
}
}).catch(err => {
console.log(err)
})
},
// 获取评价列表
getMyEvalEntryList () {
let { termId, classId } = this
this.$api.SQEEvalApi.getMyEvalEntryList({
termId: termId,
inputClassId: classId
}).then(res => {
let data = res.data
if (data.Status) {
let list = JSON.parse(JSON.stringify(data.Data.filter(item => item.eval_type !== 3)))
this.allEvalItems = list
this.recordData = list
let classArr = [{ name: '全部班级', value: 'all' }]
this.filterData.classList = classArr.concat(removeRepeatByKey(list, 'class_id').map(item => ({ name: item.class_name, value: item.class_id })))
this.$nextTick(() => {
this.searchText = `${this.$refs['search'].$refs['classPicker'].getNameValues()}`
})
}
}).catch(err => {
console.log(err)
})
},
getStateText () {
const { states } = this.filterInit
let text = ''
switch (states) {
case 0:
text = '未录入'
break
case 1:
text = '已录入'
break
case 2:
text = '录入中'
break
case 10:
text = '全部'
break
}
return `${text}班级`
},
handleEvalItemFilter () {
let { classId } = this.filterInit
const allItems = JSON.parse(JSON.stringify(this.allEvalItems))
this.recordData = classId[0] === 'all' ? allItems : allItems.filter(item => item.class_id === classId[0])
},
handleSearchClick () {
if (this.isExam) {
this.getMyExamEntryList()
this.$nextTick(() => {
this.searchText = `${this.$refs['search'].$refs['termPicker'].getNameValues()}-${this.getStateText()}`
})
} else {
this.handleEvalItemFilter()
this.$nextTick(() => {
this.searchText = `${this.$refs['search'].$refs['classPicker'].getNameValues()}`
})
}
this.showSearch = false
}
}
}
</script>
<style lang="less" scoped>
.container {
.content {
background: #fff;
}
}
</style>
<template>
<div class="card-wrap">
<div class="card-content">
<div class="card-title_wrap flex">
<span class="card-title flex-1">{{ isExam ? data.exam_name : `${data.type_name}-${data.item_name}`}}</span>
<span class="state" :class="data.states | stateClassFilter" v-if="isExam">{{ data.states | stateFilter }}</span>
</div>
<div class="card-info">班级:{{ data.class_name }}</div>
<div class="card-info">科目:{{ data.subject_name }}</div>
</div>
<div class="flex border-top">
<template v-if="isExam">
<a href="javascript:;" class="flex-1 enter-btn border-right" v-if="data.states === 1" @click="handleFinishAction(1)">申请修改</a>
<a href="javascript:;" class="flex-1 enter-btn border-right" v-if="data.states === 1" @click="handleFinishAction(2)">查看</a>
<a href="javascript:;" class="flex-1 enter-btn border-right" v-if="data.states !== 1" @click="handleEnterClick(1)">{{ data.states === 2 ? '继续录入': '开始录入' }}</a>
<a href="javascript:;" class="flex-1 enter-btn" @click="handleEnterClick(2)">考试分析录入</a>
</template>
<a href="javascript:;" v-else class="flex-1 enter-btn" @click="handleEvalEnterClick">录入</a>
</div>
</div>
</template>
<script>
import { showToast } from '@/assets/utils/message.js'
export default {
name: 'VCard',
props: {
isExam: {
type: Boolean,
default: true
},
data: {
type: Object,
default: () => ({})
},
termId: {
type: Array,
default: () => []
},
currentTermId: {
type: String,
default: ''
}
},
components: {
},
data () {
return {
}
},
computed: {},
watch: {
},
filters: {
stateFilter (v) {
switch (v) {
case 0:
return '未录入'
case 1:
return '已录入'
case 2:
return '录入中'
}
},
stateClassFilter (v) {
switch (v) {
case 0:
return 'red'
case 1:
return 'green'
case 2:
return 'orange'
}
}
},
created () {},
mounted () {},
methods: {
applyReEntry () {
let { b_id: bid } = this.data
this.$api.SQEExamApi.applyReEntry({
manageId: bid
}).then(res => {
let data = res.data
if (data.Status) {
showToast({ text: '操作成功' })
} else {
showToast({ text: data.ResponseError.LongMessage, type: 'warn' })
}
}).catch(err => {
console.log(err)
})
},
// type 1-申请重新录入 2-查看
handleFinishAction (type) {
let { data: { exam_b_id: examBid, grade_id: gradeId, class_id: classId, subject_id: subjectId }, termId } = this
let id = termId.length ? termId[0] : ''
if (type === 1) {
this.applyReEntry()
} else {
this.$router.push({ path: `/education/SQESystem/query?termId=${id}&examBid=${examBid}&classId=${classId}&gradeId=${gradeId}&subjectId=${subjectId}&type=0` })
}
},
// type 1-录入 2-考试分析录入
handleEnterClick (type) {
const { exam_b_id: examBid, id, class_id: classId, subject_id: subjectId } = this.data
let routeName = type === 1 ? 'enterScore' : 'examAnalysis'
let path = `/education/SQESystem/${routeName}?examBid=${examBid}&classId=${classId}&subjectId=${subjectId}&recordId=${id}&enter=1`
this.$router.push({ path })
},
// type 1-固定评价项 2-不固定评价项 3-评语录入 4-期末总评
handleEvalEnterClick () {
const { currentTermId } = this
const {
eval_type: type,
item_id: id,
// item_name: itemName,
class_id: classId,
// class_name: className,
subject_id: subjectId,
// subject_name: subjectName,
collect_type: collectType,
final_comment_entry_type: finalCommentEntryType
} = this.data
let path = ''
let routeName = ''
if (type === 1 || type === 2) {
routeName = collectType === 1 ? 'evaluationStatisticsRecord' : 'evaluationStatisticsUpload'
path = `/education/SQESystem/${routeName}?itemId=${id}&classId=${classId}&termId=${currentTermId}`
} else if (type === 3) { // 移动端不录入评语
} else if (type === 4) {
routeName = finalCommentEntryType === 1 ? 'autoEnter' : finalCommentEntryType === 2 ? 'enterLevel' : finalCommentEntryType === 3 ? 'enterScore' : ''
if (routeName === '') return false
path = `/education/SQESystem/terminalGeneralCommentEnter/${routeName}?classId=${classId}&subjectId=${subjectId}&termId=${currentTermId}`
}
this.$router.push({ path })
}
}
}
</script>
<style lang="less" scoped>
@border: 1px solid #D9D9D9;
.card-wrap {
border: @border;
margin: 10px 15px 0;
position: relative;
.border-top {
border-top: @border;
}
.border-right {
border-right: @border;
}
.card-content {
padding: 10px 15px;
font-size: 14px;
.card-title_wrap {
overflow: hidden;
align-items: center;
margin-bottom: 5px;
.card-title {
font-weight: bold;
word-break: break-all;
}
.state {
padding: 0 3px;
font-size: 13px;
margin-left: 5px;
border: 1px solid;
}
.state.red {
border-color: #D9001B;
color: #D9001B;
}
.state.orange {
border-color: #F59A23;
color: #F59A23;
}
.state.green {
border-color: #35B141;
color: #35B141;
}
}
.card-info {
margin-bottom: 5px;
color: #AAAAAA;
}
}
.enter-btn {
padding: 8px 0 ;
text-align: center;
color: #1890FF;
font-size: 15px;
}
}
</style>
<template>
<div>
<div class="search-bar" @click="showSearch = !showSearch">{{ searchText }} <i class="iconfont" :class="{ 'show-search': showSearch }">&#xe113;</i></div>
<transition name="fade">
<div class="search-wrap" v-show="showSearch">
<group gutter="0">
<popup-picker
ref="termPicker"
v-show="isExam"
value-text-align="left"
:columns="1"
placeholder="请选择"
title="学期:"
show-name
:data="data.termList"
v-model="formVal.termId"
>
</popup-picker>
<cell-box v-show="isExam">
<div class="weui-label">状态:</div>
<div>
<ul class="state-list flex">
<li class="state-item" :class="{ 'checked': item.value === formVal.states }" v-for="(item,index) in stateList" :key="`state_${index}`" @click="handleStateClick(index)">{{ item.label }}</li>
</ul>
</div>
</cell-box>
<popup-picker
ref="classPicker"
v-show="!isExam"
value-text-align="left"
:columns="1"
placeholder="请选择"
title="班级:"
show-name
:data="data.classList"
v-model="formVal.classId"
>
</popup-picker>
<cell-box class="btn-wrap">
<x-button plain class="flex-1" @click.native="handleResetClick">重置</x-button>
<x-button class="flex-1" type="primary" @click.native="handleSearchClick">查询</x-button>
</cell-box >
</group>
</div>
</transition>
</div>
</template>
<script>
import { Group, CellBox, PopupPicker, XButton } from 'vux'
import { showToast } from '@/assets/utils/message.js'
export default {
name: 'VSearch',
props: {
show: {
type: Boolean,
default: true
},
isExam: {
type: Boolean,
default: true
},
searchText: {
type: String,
default: ''
},
init: {
type: Object,
default: () => ({
termId: [],
states: 10,
classId: []
})
},
data: {
type: Object,
default: () => ({
termList: [],
classList: []
})
}
},
components: {
Group,
CellBox,
PopupPicker,
XButton
},
data () {
return {
stateList: [ { label: '全部', value: 10 }, { label: '未录入', value: 0 }, { label: '录入中', value: 2 }, { label: '已录入', value: 1 } ]
}
},
computed: {
formVal: {
get () {
return this.init
},
set (val) {
this.$emit('update:init', val)
}
},
showSearch: {
get () {
return this.show
},
set (val) {
this.$emit('update:show', val)
}
}
},
created () {
},
mounted () {},
methods: {
handleStateClick (i) {
this.formVal.states = this.stateList[i].value
},
handleResetClick () {
this.formVal.termId = []
this.formVal.states = 10
this.formVal.classId = []
},
handleSearchClick () {
let { formVal: { termId, classId }, isExam } = this
if (isExam && !termId.length) return showToast({ text: '请先选择学期', type: 'cancel' })
if (!isExam && !classId.length) return showToast({ text: '请先选择班级', type: 'cancel' })
this.$emit('search', this.formVal)
}
}
}
</script>
<style lang="less" scoped>
.search-bar {
font-size: 15px;
text-align: center;
padding: 10px 0 ;
cursor: pointer;
.iconfont {
display: inline-block;
margin-left: 6px;
color: #419df7;
transition: all .3s;
}
.iconfont.show-search {
transform: rotate(-180deg);
}
}
.search-wrap {
/deep/.weui-cells {
.vux-cell-value {
color: #333;
}
.weui-btn + .weui-btn {
margin-top: 0;
margin-left: 20px;
}
.weui-btn {
line-height: 1.65 !important;
}
.btn-wrap {
padding: 10px 15px;
}
}
.state-list {
.state-item {
cursor: pointer;
margin: -10px 0;
padding: 10px 0;
}
.state-item:not(:first-child) { margin-left: 10px; }
.state-item.checked { color: #419df7; }
}
}
.fade-enter-active, .fade-leave-active {
transition: all .1s ease-in-out;
height: 0;
}
.fade-leave, .fade-leave-active {
height: auto;
}
</style>
<template>
<div class="card-wrap_box">
<v-card v-for="(item,index) in data" :key="`record_${index}`" :data="item" :is-exam="isExam" :term-id="termId" :current-term-id="currentTermId"></v-card>
</div>
</template>
<script>
export default {
name: 'Evaluation',
props: {
isExam: {
type: Boolean,
default: true
},
data: {
type: Array,
default: () => []
},
termId: {
type: Array,
default: () => []
},
currentTermId: {
type: String,
default: ''
}
},
components: {
VCard: () => import('./../components/VCard')
},
data () {
return {
}
},
created () {},
mounted () {},
methods: {}
}
</script>
<style lang="less" scoped>
.card-wrap_box {
padding-top: 15px;
}
</style>
<template>
<div class="card-wrap_box">
<v-card v-for="(item,index) in data" :key="`record_${index}`" :data="item" :is-exam="isExam" :term-id="termId" :current-term-id="currentTermId"></v-card>
</div>
</template>
<script>
export default {
name: 'Exam',
props: {
isExam: {
type: Boolean,
default: true
},
data: {
type: Array,
default: () => []
},
termId: {
type: Array,
default: () => []
},
currentTermId: {
type: String,
default: ''
}
},
components: {
VCard: () => import('./../components/VCard')
},
data () {
return {
}
},
created () {},
mounted () {},
methods: {}
}
</script>
<style lang="less" scoped>
.card-wrap_box {
padding-top: 15px;
}
</style>
<template>
<div class="container">
<div class="fixed-wrapper">
<page-header-eva
title="记录情况"
:routers="routerArr"
:page-title="pageTitle"
current="/education/SQESystem/evaluationEnterRecordList">
</page-header-eva>
</div>
<div class="content">
<div>
<ul class="list" v-if="list.length">
<li class="item"
v-for="(item, index) of list"
:key="`item_key_${index}`"
:class="item.is_spread ? 'active' : ''">
<a href="javascript:;" class="item-content" @click="item.is_spread = !item.is_spread"></a>
<div class="input-wrapper">
<input type="text" class="short-input" v-model="item.record_name" maxlength="4" ref="shortInput">
</div>
<div class="item-btn-group">
<a href="JavaScript:;" class="btn-item" @click="handleEditClick(item.b_id, item.record_name)">
<i class="icon icon-compose"></i>
<p>编辑</p>
</a>
<a href="javascript:;" class="btn-item" @click="handleDeleteClick(index, item.b_id)">
<i class="icon icon-trash"></i>
<p>删除</p>
</a>
</div>
</li>
</ul>
<div class="data-empty" v-else>
<div class="wrapper text-center">
<img src="@/assets/images/empty.png" alt="">
<p>无记录数据,请先添加记录!</p>
</div>
</div>
<div class="content-padded">
<a href="javascript:;" class="add-btn" @click="handleAddClick">
<i class="icon icon-plusempty"></i>添加
</a>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'EvaluationEnterRecordList',
props: {
data: {
type: Object,
default: () => ({
itemId: '',
classId: '',
termId: ''
})
}
},
components: {
PageHeaderEva: () => import('pages/education/SQESystem/PageHeaderEva')
},
data () {
return {
routerArr: [
// {
// path: '/education/SQESystem/evaluationEnterRecordList',
// name: '记录情况'
// },
{
path: '/education/SQESystem/evaluationStatisticsRecord',
name: '统计情况'
},
{
path: '/education/SQESystem/enterTerminalGrade',
name: '期末总评'
}
],
list: [],
pageTitle: ''
// routerParams: this.$route.params
}
},
created () {
this.getClassSubjectItemRecordList()
},
methods: {
handleAddClick () {
this.list.push({
record_name: `记录${this.list.length + 1}`,
b_id: 'add',
is_spread: true,
create_time: '',
id: 0
})
this.$nextTick(() => {
this.$refs.shortInput[this.list.length - 1].focus()
})
},
// 获取班级科目记录列表
getClassSubjectItemRecordList () {
const { itemId, classId, termId } = this.data
this.$api.SQEEvalApi.getClassSubjectItemRecordList({
termId,
classId,
itemId
}).then(res => {
let data = res.data
if (data.Status) {
this.list = data.Data.map(item => (Object.assign({ is_spread: false }, item)))
} else {
this.toastInfo(data.ResponseError.LongMessage)
}
})
},
// 编辑
handleEditClick (id, name) {
if (name.replace(/\s*/g, '') === '') {
this.toastInfo('请输入名称', 'warn')
return
}
this.$router.push({
path: `/education/SQESystem/evaluationEnterRecord/${id}/${this.routerParams.itemId}/${this.routerParams.classId}/${this.routerParams.termId}/${name}`
})
},
// 删除
handleDeleteClick (idx, id) {
if (id === 'add') {
this.list.splice(idx, 1)
} else {
this.$vux.confirm.show({
title: '提示',
content: '确认删除已创建好的记录吗?',
onConfirm: () => {
const { itemId, classId } = this.data
this.$api.SQEEvalApi.deleteRecordScore({
classId,
itemId,
recordId: id
}).then(res => {
let data = res.data
if (data.Status) {
this.toastInfo('删除成功', 'success')
this.list.splice(idx, 1)
} else {
this.toastInfo(data.ResponseError.LongMessage)
}
})
}
})
}
},
// 提示信息
toastInfo (text, type = 'cancel') {
this.$vux.toast.show({
text,
type
})
}
}
}
</script>
<style lang="stylus" scoped>
.data-empty
display flex
justify-content center
padding-top 100px
img
width 100px
height 82px
p
margin-bottom 0
text-align center
.list
position relative
background-color #fff
.item
position relative
overflow hidden
&:after
content ''
position absolute
bottom 0
left 0
right 0
height 1px
background-color #c8c7cc
transform scaleY(0.5)
.input-wrapper
position absolute
height 44px
line-height 44px
width 100px
left 15px
top 0
input[type="text"]
height 100%
line-height 44px
padding 0
margin 0
border-radius 0
border none
.item-content
display block
position relative
height 44px
line-height 44px
padding 0 30px 0 15px
color #333
&:after
content '\e581'
position absolute
font-family Muiicons
font-size inherit
line-height 1
top 50%
right 15px
transform translateY(-50%)
color #bbb
-webkit-font-smoothing antialiased
.item-btn-group
position relative
padding 6px 15px
text-align center
background-color #fafbff
font-size 0
display none
&:after
content ''
position absolute
top 0
left 0
right 0
height 1px
background-color #c8c7cc
transform scaleY(0.5)
.btn-item
display inline-block
width 60px
text-align center
color #b6b6b6
.icon-trash:before
content '\e401'
p
margin-bottom 0
&.active
.item-content
&:after
content '\e580'
.item-btn-group
display block
.add-btn
display block
line-height 43px
text-align center
color #999
border 1px dashed #ddd
background-color #fff
border-radius 5px
.icon-plusempty:before
content: '\e468'
</style>
<template>
<div class="container">
<v-header title="评价管理"></v-header>
<div class="content flex-column">
<router-tab :tab-list="tabList" :term-id="$route.params.termId" v-if="isHeaerTeacher"></router-tab>
<router-view :list="list" :term-id="$route.params.termId" @spread="handleSpreadClick" :class-id="classId" :class-name="className"></router-view>
</div>
</div>
</template>
<script>
import VHeader from '@/common/header/VHeader'
import RouterTab from './../RouterTab'
export default {
name: 'EvaluationManage',
components: {
VHeader,
RouterTab
},
data () {
return {
tabList: [
{
name: '科教教师录入',
path: '/SQESystem/evaluationManage/regularTeacher',
type: 1,
pathName: 'RegularTeacher'
},
{
name: '班主任录入',
path: '/SQESystem/evaluationManage/headTeacher',
type: 2,
pathName: 'HeadTeacher'
}
],
entryTeacherType: 1,
list: [],
isHeaerTeacher: false,
classId: '',
className: ''
}
},
watch: {
'$route' (to, from) {
console.log(to.name)
let type = to.name === 'RegularTeacher' ? 1 : 2
this.list = []
this.entryTeacherType = type
this.getEvalManagerList()
}
},
methods: {
// 获取班级评价列表
getEvalManagerList () {
this.$api.SQEEvalApi.getEvalManagerList({
termId: this.$route.params.termId,
entry_teacher_type: this.entryTeacherType
}).then(res => {
let data = res.data
if (data.Status) {
let rep = data.Data
this.isHeaerTeacher = rep.is_head_teacher
if (this.entryTeacherType === 1) {
// 科教老师录入
let result = rep.list.map(item => Object.assign({ spread: false }, item))
this.list = result
} else {
this.list = rep.data.list
this.classId = rep.data.class_id
this.className = rep.data.class_name
}
} else {
this.toastInfo(data.ResponseError.LongMessage)
}
})
},
// 展开
handleSpreadClick (idx) {
this.list[idx].spread = !this.list[idx].spread
},
// 提示信息
toastInfo (text, type = 'cancel') {
this.$vux.toast.show({
text,
type
})
}
},
created () {
this.entryTeacherType = this.$route.name === 'RegularTeacher' ? 1 : 2
this.getEvalManagerList()
}
}
</script>
<style lang="stylus" scoped>
</style>
<template>
<div class="scroll-wrap" ref="scrollWrapper">
<div>
<ul class="list">
<li class="list-item">
<div class="item-title">
{{ className }}
</div>
<div class="inner-list-wrapper">
<div class="sub-list-item" v-for="(item, index) of list" :key="`eval_item_${index}`" >
<div class="inner-list-title">{{ item.eval_type_name }}</div>
<ul class="inner-list" v-if="item.items.length">
<li class="inner-list-item" v-for="(innerItem, innerIndex) of item.items" :key="`eval_item_${index}_${innerIndex}`">
<router-link
:to="
innerItem.collect_type === 1
? `/education/SQESystem/evaluationEnterRecordList/${innerItem.b_id}/${classId}/${termId}/${innerItem.item_name}/${className}`
: `/education/SQESystem/evaluationStatisticsUpload/${innerItem.b_id}/${classId}/${termId}/${innerItem.item_name}/${className}`
"
>
{{ innerItem.item_name }}{{ innerItem.final_exam_entry_model === 1 ? `${innerItem.final_max_score}分` : '等级' }}
</router-link>
</li>
</ul>
<div class="empty-wrapper" v-else>
<i class="icon1">&#xe70b;</i>
未配置评价项
</div>
</div>
</div>
</li>
</ul>
<!-- <div class="data-empty">
<div class="wrapper text-center">
<img src="@/assets/images/empty.png" alt="" />
<p>暂无数据</p>
</div>
</div> -->
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
name: 'HeadTeacher',
props: {
list: {
type: Array,
default: () => [
{
eavl_type_id: '',
eval_type_name: ''
}
]
},
termId: {
type: String
},
classId: {
type: String
},
className: {
type: String
}
},
data () {
return {
scroll: null,
data: []
}
},
watch: {
list (newValue, oldValue) {
this.$nextTick(() => {
this.scroll = new BScroll(this.$refs.scrollWrapper, {
click: true
})
})
}
}
}
</script>
<style lang="stylus" scoped>
.scroll-wrap
position relative
flex 1
overflow hidden
.data-empty
position absolute
top 0
right 0
left 0
bottom 0
background-color #fff
display flex
justify-content center
padding-top 100px
img
width 100px
height 82px
p
margin-bottom 0
text-align center
.inner-list-title
position relative
margin-left 15px
padding-left 15px
line-height 18px
color #8f8f94
font-size 15px
&:before
content ''
position absolute
top 0px
left 0
width 9px
height 7px
border-width 1px
border-style solid
border-color transparent transparent #8f8f94 #8f8f94
.list
position relative
background-color #fff
.list-item
position relative
overflow hidden
&:after
content ''
position absolute
bottom 0
left 0
right 0
height 1px
transform scaleY(0.5)
background-color #c8c7cc
.item-title
position relative
padding 10px 56px 10px 12px
.spread-btn
position absolute
top 0
right 0
bottom 0
padding 10px 12px
color #409EFF
.inner-list
margin-left 35px
.inner-list-item
position relative
padding 15px 36px 15px 0
color #333
padding-right 36px
&:not(:last-child):after
content ''
position absolute
bottom 0
left 0
right 0
height 1px
transform scaleY(0.5)
background-color #c8c7cc
&>a
display flex
justify-content space-between
position relative
color inherit
padding inherit
margin -15px -36px -15px 0
&:after
right 10px
content '\e583'
font-family Muiicons
font-size inherit
line-height 1
position absolute
top 50%
display inline-block
-webkit-transform translateY(-50%)
transform translateY(-50%)
text-decoration none
color #bbb
-webkit-font-smoothing antialiased
.status
flex-shrink 0
margin-left 8px
color #8f8f94
display flex
align-items center
&:before
content ''
display inline-block
width 6px
height 6px
margin-right 3px
border-radius 50%
background-color transparent
&.success
&:before
background-color #09bb07
&.danger
&:before
background-color #ea4335
&.warning
&:before
background-color #f6a623
.empty-wrapper
padding 15px 0
text-align center
font-size 13px
color #8f8f94
.icon1
font-size 16px
</style>
<template>
<div class="scroll-wrap" ref="scrollWrapper">
<div>
<ul class="list" v-if="list.length">
<li class="list-item" v-for="(item, index) of list" :key="`eval_item_${index}`">
<div class="item-title">
{{ item.class_class }}&nbsp;&nbsp;{{ item.subject_name }}
<a href="javascript:;" class="spread-btn" @click="handleSpreadClick(index)">{{ item.spread ? '收起' : '展开' }}</a>
</div>
<template v-if="item.eval_items.length">
<div class="inner-list-wrapper" v-show="item.spread">
<div class="sub-item" v-for="(innerItem, innerIndex) of item.eval_items" :key="`eval_item_${index}_${innerIndex}`">
<div class="inner-list-title">{{ innerItem.eval_type_name }}</div>
<ul class="inner-list" v-if="innerItem.items.length">
<li class="inner-list-item" v-for="(subInnerItem, subInnerIndex) of innerItem.items" :key="`eval_item_${index}_${innerIndex}_${subInnerIndex}`">
<router-link
:to="
subInnerItem.collect_type === 1
? `/education/SQESystem/enterTerminalGrade/${subInnerItem.b_id}/${item.class_id}/${termId}/${subInnerItem.item_name}/${item.class_class}/${item.subject_name}`
: `/education/SQESystem/evaluationStatisticsUpload/${subInnerItem.b_id}/${item.class_id}/${termId}/${subInnerItem.item_name}/${item.class_class}/${item.subject_name}`
"
>
{{ subInnerItem.item_name }}{{ subInnerItem.final_exam_entry_model === 1 ? `${subInnerItem.final_max_score}分` : '等级' }}
</router-link>
</li>
</ul>
<div class="empty-wrapper" v-else>
<i class="icon1">&#xe70b;</i>
未配置评价项
</div>
</div>
</div>
</template>
<template v-else>
<div class="empty-wrapper" v-show="item.spread">
<i class="icon1">&#xe70b;</i>
无个人考试资料
</div>
</template>
</li>
</ul>
<div class="data-empty" v-else>
<div class="wrapper text-center">
<img src="@/assets/images/empty.png" alt="" />
<p>没有你需要录入的评价!</p>
</div>
</div>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
name: 'RegularTeacher',
props: {
list: {
type: Array
},
termId: {
type: String
}
},
data () {
return {
scroll: null
}
},
watch: {
list (newValue, oldValue) {
this.$nextTick(() => {
this.scroll = new BScroll(this.$refs.scrollWrapper, {
click: true
})
})
}
},
methods: {
handleSpreadClick (idx) {
this.$emit('spread', idx)
}
}
}
</script>
<style lang="stylus" scoped>
.scroll-wrap
position relative
flex 1
overflow hidden
.data-empty
position absolute
top 0
right 0
left 0
bottom 0
background-color #fff
display flex
justify-content center
padding-top 100px
img
width 100px
height 82px
p
margin-bottom 0
text-align center
.list
position relative
background-color #fff
.list-item
position relative
overflow hidden
&:after
content ''
position absolute
bottom 0
left 0
right 0
height 1px
transform scaleY(0.5)
background-color #c8c7cc
.item-title
position relative
padding 10px 56px 10px 12px
.spread-btn
position absolute
top 0
right 0
bottom 0
padding 10px 12px
color #409EFF
.inner-list-wrapper
padding 0 12px
.sub-item
& + .sub-item
margin-top 10px
.inner-list-title
position relative
padding-left 15px
line-height 18px
color #8f8f94
font-size 15px
&:before
content ''
position absolute
top 0px
left 0
width 9px
height 7px
border-width 1px
border-style solid
border-color transparent transparent #8f8f94 #8f8f94
.inner-list
margin-left 20px
.inner-list-item
position relative
padding 15px 36px 15px 0
color #333
padding-right 36px
&:after
content ''
position absolute
bottom 0
left 0
right 0
height 1px
transform scaleY(0.5)
background-color #c8c7cc
&>a
display flex
justify-content space-between
position relative
color inherit
padding inherit
margin -15px -36px -15px 0
&:after
right 10px
content '\e583'
font-family Muiicons
font-size inherit
line-height 1
position absolute
top 50%
display inline-block
-webkit-transform translateY(-50%)
transform translateY(-50%)
text-decoration none
color #bbb
-webkit-font-smoothing antialiased
.status
flex-shrink 0
margin-left 8px
color #8f8f94
display flex
align-items center
&:before
content ''
display inline-block
width 6px
height 6px
margin-right 3px
border-radius 50%
background-color transparent
&.success
&:before
background-color #09bb07
&.danger
&:before
background-color #ea4335
&.warning
&:before
background-color #f6a623
&:last-child
.inner-list-item:last-child
&:after
background-color transparent
.empty-wrapper
padding 15px 0
text-align center
font-size 13px
color #8f8f94
.icon1
font-size 16px
</style>
<template>
<div class="container">
<div class="fixed-wrapper">
<page-header-eva
title="统计情况"
:routers="routerArr"
:class-name="routerParams.className"
:subject-name="routerParams.subjectName"
:item-name="routerParams.itemName"
:page-title="pageTitle"
current="/education/SQESystem/evaluationStatisticsRecord"></page-header-eva>
<!-- <first-name :disable-grade="false"></first-name> -->
<first-name
:disable-grade="false"
:first-name="firstName"
@changeName="handleFirstNameChange"
@changeSort="handleSortChange"></first-name>
</div>
<div class="content flex-column">
<div class="thead">
<div class="left-fixed-thead" :class="Math.abs(horizontalScrollX) > 0 ? 'active' : ''">
<div class="flex-width40">#</div>
<div class="flex-width120">学生</div>
</div>
<div
class="right-scroll-thead"
ref="rightScrollThead"
:style="{ width: `${fieldWidth}`, transform: `translateX(${horizontalScrollX}px)`}">
<div class="flex-width80" v-for="(item, index) of fieldList" :key="`field_item_${index}`">{{ item.name }}</div>
</div>
</div>
<div class="tbody-wrapper" ref="scrollWrapper">
<div class="clearfix">
<div class="left-fixed" :class="Math.abs(horizontalScrollX) > 0 ? 'active' : ''" >
<div class="tbody">
<ul class="list">
<li class="item"
:class="currentFirstName === item.student_name.slice(0, 1) ? 'active' : ''"
v-for="(item, index) of studentDataList"
:key="`student_item_${index}`">
<div class="flex-width40">{{ index + 1 }}</div>
<div class="flex-width120">
{{ item.student_name }}
<p>{{ item.student_code }}</p>
</div>
</li>
</ul>
</div>
</div>
<div class="right-scroll" ref="rightWrapper" :style="{ width: originWidth - 160 + 'px' }">
<div :style="{ width: `${fieldWidth}` }">
<div class="tbody">
<ul class="list">
<li
class="item"
:class="currentFirstName === item.student_name.slice(0, 1) ? 'active' : ''"
v-for="(item, index) of studentDataList"
:key="`student_score_item_${index}`">
<div class="flex-width80" v-for="(innerItem, innerIndex) of item.statistic" :key="`inner_item_${innerIndex}`">{{ innerItem.number }}</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
name: 'EvaluationStatisticsRecord',
props: {
data: {
type: Object,
default: () => ({
itemId: '',
classId: '',
termId: ''
})
}
},
components: {
PageHeaderEva: () => import('pages/education/SQESystem/PageHeaderEva'),
FirstName: () => import('pages/education/SQESystem/FirstName')
},
data () {
return {
scroll: null,
horizontalScroll: null,
routerParams: this.$route.params,
sortType: 1,
firstName: [],
currentFirstName: '',
fieldList: [],
studentDataList: [],
originWidth: '',
horizontalScrollX: 0,
routerArr: [
// {
// path: '/education/SQESystem/evaluationEnterRecordList',
// name: '记录情况'
// },
{
path: '/education/SQESystem/evaluationStatisticsRecord',
name: '统计情况'
},
{
path: '/education/SQESystem/enterTerminalGrade',
name: '期末总评'
}
],
isOpenEnter: true,
pageTitle: '',
timeout: null
}
},
computed: {
fieldWidth () {
let originWidth = document.body.clientWidth
let result = ''
let computFiledListWidth = this.fieldList.length * 80
if (computFiledListWidth >= originWidth - 160) {
result = `${computFiledListWidth}px`
} else {
result = `${originWidth - 160}px`
}
return result
}
},
created () {
this.getEntryEvalScoreListForRecorType()
},
mounted () {
this.$nextTick(() => {
this.listScroll()
})
},
beforeDestroy () {
window.clearTimeout(this.timeout)
},
methods: {
listScroll () {
let originWidth = document.body.clientWidth
this.originWidth = originWidth
this.scroll = new BScroll(this.$refs.scrollWrapper, {
probeType: 3
})
this.horizontalScroll = new BScroll(this.$refs.rightWrapper, {
scrollX: true,
bounce: false,
eventPassthrough: 'vertical',
probeType: 3
})
this.horizontalScroll.on('scroll', ({x, y}) => {
this.horizontalScrollX = x
})
},
// 获取统计记录
getEntryEvalScoreListForRecorType () {
const { sortType, data: { classId, itemId, termId } } = this
this.$api.SQEEvalApi.getEntryEvalScoreListForRecorType({
itemId,
classId,
sortType,
termId,
isExport: false
}).then(res => {
let data = res.data
if (data.Status) {
this.firstName = data.Data.first_name
this.fieldList = data.Data.data[0].statistic
this.studentDataList = data.Data.data
this.pageTitle = data.Data.title
} else {
this.toastInfo(data.ResponseError.LongMessage)
}
})
},
// 点击姓名
handleFirstNameChange (val) {
let { studentDataList: studentListArr } = this
let i = null
for (let j = 0; j < studentListArr.length; j++) {
let item = studentListArr[j]
if (item.student_name.substring(0, 1) === val) {
i = j
break
}
}
let studentList = this.$refs.scrollWrapper.getElementsByClassName('item')
let el = studentList[i]
this.scroll.scrollToElement(el, 300)
this.currentFirstName = val
window.clearTimeout(this.timeout)
this.timeout = window.setTimeout(() => { this.currentFirstName = '' }, 1000)
},
// 切换排序
handleSortChange (value) {
this.sortType = value
this.getEntryEvalScoreListForRecorType()
},
// 提示信息
toastInfo (text, type = 'cancel') {
this.$vux.toast.show({
text,
type
})
}
}
}
</script>
<style lang="stylus" scoped>
.tbody-wrapper
flex 1
overflow hidden
.thead
display flex
height 36px
line-height 34px
border-bottom 2px solid #666
color #999
background-color #fff
font-weight 600
overflow hidden
.left-fixed-thead
position relative
display flex
flex 0 0 160px
background-color #fff
&.active
&:after
content ''
position absolute
top 0
bottom 0
right 0
width 4px
background: linear-gradient(to right, #f4f4f4 , rgba(244, 244, 244, 0));
z-index 1
.right-scroll-thead
display flex
flex 1
.tbody
overflow hidden
.list
position relative
background-color #fff
.item
position relative
height 48px
display flex
align-items center
font-size 14px
overflow hidden
&:after
content ''
position absolute
bottom 0
left 0
right 0
height 1px
-webkit-transform scaleY(0.5)
transform scaleY(0.5)
background-color #c8c7cc
&.active
background-color #ecf5ff
&:after
background-color #d2dde8
p
margin-bottom 0
.flex-width40
flex 0 0 40px
padding-left 8px
.flex-width80
flex 0 0 80px
padding-left 8px
.flex-width120
flex 0 0 120px
padding-left 8px
.left-fixed
position relative
width 160px
float left
&.active
&:after
content ''
position absolute
top 0
bottom 0
right 0
width 4px
background: linear-gradient(to right, #f4f4f4 , rgba(244, 244, 244, 0));
.right-scroll
float left
height auto
width auto
overflow hidden
</style>
<template>
<div class="container">
<v-header title="考试管理"></v-header>
<div class="content flex-column">
<router-tab :tab-list="tabList" :term-id="termId"></router-tab>
<router-view :table-list="tableListArr"></router-view>
</div>
</div>
</template>
<script>
import VHeader from '@/common/header/VHeader'
import RouterTab from './../RouterTab'
export default {
name: 'ExamManage',
components: {
VHeader,
RouterTab
},
data () {
return {
tabList: [
{
name: '我任教的',
path: '/SQESystem/examManage/mine'
},
{
name: '交叉录成绩的',
path: '/SQESystem/examManage/mix'
}
],
termId: this.$route.params.termId,
tableListArr: [],
examDataObj: {
chanage: [],
school: []
}
}
},
watch: {
'$route' (to, form) {
if (to.name === 'ExamManageMine') {
this.tableListArr = this.examDataObj.school
} else {
this.tableListArr = this.examDataObj.chanage
}
}
},
methods: {
getExamOfTeacheringSubjects () {
this.$api.SQEExamApi.getExamOfTeacheringSubjects({
termId: this.termId
}).then(res => {
let data = res.data
if (data.Status) {
let examDataObj = data.Data
if (examDataObj.school.length) {
examDataObj.school = examDataObj.school.map(item => Object.assign(item, { isOpen: false }))
}
if (examDataObj.chanage.length) {
examDataObj.chanage = examDataObj.chanage.map(item => Object.assign(item, { isOpen: false }))
}
if (this.$route.name === 'ExamManageMine') {
this.tableListArr = examDataObj.school
} else {
this.tableListArr = examDataObj.chanage
}
this.examDataObj = examDataObj
}
}).catch(err => {
console.log(err)
})
}
},
mounted () {
},
created () {
// console.log(this.$router,this.$route.name)
this.getExamOfTeacheringSubjects()
}
}
</script>
<style lang="stylus" scoped>
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment