Просмотр исходного кода

Merge branch 'develop5.0-tmd' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop5.0-tmd

CrazyIter_Bin 4 лет назад
Родитель
Сommit
b8b726a512

+ 6 - 6
TEAMModelOS/ClientApp/src/view/schoolmgmt/SystemSetting/NewSystemSetting.less

@@ -529,7 +529,7 @@
     .arrow-box{
         position: absolute;
         top: 2px;
-        margin-left: 2px;
+        margin-left: 1px;
     }
     .line-box{
         display: flex;
@@ -537,8 +537,8 @@
     }
     .time-dot {
         position: relative;
-        width: 20px;
-        height: 20px;
+        width: 18px;
+        height: 18px;
         border-radius: 50%;
         padding: 5px;
         border: 2px solid #959595;
@@ -548,8 +548,8 @@
 
     .time-inner-dot {
         display: inline-block;
-        width: 8px;
-        height: 8px;
+        width: 6px;
+        height: 6px;
         background: #959595;
         border-radius: 50%;
         position: absolute;
@@ -564,7 +564,7 @@
         width: 35px;
         margin-top: 9px;
         border-top: 2px solid #606060;
-        width: ~"calc(100% - 20px)";
+        width: ~"calc(100% - 18px)";
     }
     .arrow-item{
         display: block;

+ 75 - 22
TEAMModelOS/ClientApp/src/view/schoolmgmt/SystemSetting/NewSystemSetting.vue

@@ -277,6 +277,7 @@
                 </div>
             </Split>
         </div>
+        <!-- 添加校区 -->
         <Modal v-model="campusStatus" class="campus-modal dark-iview-modal" @on-cancel="selectedCampusIndex = -1" @on-ok="confirmCampus" @click.native="initStatus">
             <p slot="header" style="color:#DDDDDD;letter-spacing:2px;font-weight:400;">{{$t('schoolBaseInfo.setCampus')}}</p>
             <p v-for="(item,index) in schoolSetting.campuses" class="campus-name-item dark-iview-input disabled-iview-select text-cursor-disabled" :key="index" @click.stop="selectedCampusIndex = index">
@@ -287,6 +288,7 @@
             </p>
             <Icon type="md-add-circle" size="40" style="margin:auto;cursor:pointer;margin-top:30px;" @click="addCampus" />
         </Modal>
+        <!-- 添加学科 -->
         <Modal v-model="addSubStatus" class="dark-iview-modal dark-iview-form dark-iview-input" :title="$t('schoolBaseInfo.addSubject')" @on-cancel="cancelSubject" @on-ok="confirmSubject">
             <Form ref="subjectInfo" :model="subjectInfo" class="add-subject-form" label-colon>
                 <!-- 学科类型 -->
@@ -326,12 +328,43 @@
                 </FormItem>
             </Form>
         </Modal>
+        <!-- 添加学期 -->
+        <Modal v-model="addSemStatus" class="dark-iview-modal dark-iview-form dark-iview-input" title="添加学期" @on-cancel="cancelSemester" @on-ok="confirmSemester">
+            <Form ref="semesterInfo" :model="semtInfo" class="add-subject-form" label-colon :label-width="80" label-position="left">
+                <!-- 学科类型 -->
+                <FormItem prop="name" label="名称">
+                    <Input v-model="semtInfo.name" style="width:200px" :placeholder="$t('schoolBaseInfo.nameWarning')"></Input>
+                </FormItem>
+                <!-- 开始时间 -->
+                <FormItem prop="name" label="开始于">
+                    <Select v-model="semtInfo.month" style="width:80px" :placeholder="$t('schoolBaseInfo.monthHolder')">
+                        <Option v-for="(item,index) in monthList" :value="(index + 1)" :key="index" @click.native="countSemDays">{{ item }}</Option>
+                    </Select>
+                    <span> / </span>
+                    <Select v-model="semtInfo.day" style="width:80px" :placeholder="$t('schoolBaseInfo.dayHolder')">
+                        <Option v-for="(item,index) in dayList" :value="(index + 1)" :key="index" @click.native="countSemDays">{{ item }}</Option>
+                    </Select>
+                </FormItem>
+                <!-- 是否为入学期 -->
+                <FormItem prop="name" label="入学期">
+                    <RadioGroup v-model="semtInfo.start">
+                        <Radio label="1">
+                            <span>是</span>
+                        </Radio>
+                        <Radio label="0" style="margin-left:30px">
+                            <span>否</span>
+                        </Radio>
+                    </RadioGroup>
+                </FormItem>
+
+            </Form>
+        </Modal>
 
     </div>
 </template>
 
 <script>
-import BlobTool from '@/utils/blobTool.js'
+// import BlobTool from '@/utils/blobTool.js'
 import Draggable from 'vuedraggable'
 import TimeSetting from '@/view/newcourse/TimeSetting.vue'
 import '@/utils/Math.uuid'
@@ -341,6 +374,13 @@ export default {
     },
     data() {
         return {
+            semtInfo: {
+                id: '',
+                name: '',
+                month: '',
+                day: '',
+                start: ''
+            },
             defBadge: undefined,
             subjectInfo: {
                 type: '',
@@ -349,6 +389,7 @@ export default {
                 isNew: '0'
             },
             addSubStatus: false,
+            addSemStatus: false,
             tab: 'common',
             addTypeStatus: false,
             typeItem: {
@@ -402,6 +443,18 @@ export default {
         }
     },
     methods: {
+        confirmSemester() {
+
+        },
+        cancelSemester() {
+            this.semtInfo = {
+                id: '',
+                name: '',
+                month: '',
+                day: '',
+                start: ''
+            }
+        },
         customUpload(file) {
             let format = ['png', 'jpg', 'jpeg'] //头像文件格式
             let extension = file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length)
@@ -432,8 +485,7 @@ export default {
             //     }
             // )
         },
-        success(response, file, fileList){
-            // console.log(response, file, fileList)
+        success(response, file, fileList) {
             this.schoolSetting.picture = response.url
         },
         /**
@@ -1098,25 +1150,26 @@ export default {
         },
         // 添加学期
         addSemester() {
-            let semLen = this.schoolSetting.period[this.curPriodIndex].semesters.length
-            if (semLen < this.TERM_MAX_LENGTH) {
-                let defMonth = semLen == 0 ? 1 : this.schoolSetting.period[this.curPriodIndex].semesters[semLen - 1].month + 1
-                this.schoolSetting.period[this.curPriodIndex].semesters.push({
-                    name: this.$t('schoolBaseInfo.persetSemester') + (this.schoolSetting.period[this.curPriodIndex].semesters.length + 1),
-                    month: defMonth,
-                    day: 26,
-                    id: this.guid()
-                })
-                this.countSemDays()
-                this.$nextTick(() => {
-                    setTimeout(() => {
-                        this.curSemIndex = this.schoolSetting.period[this.curPriodIndex].semesters.length - 1
-                        this.editSemIndex = this.curSemIndex
-                    }, 200)
-                })
-            } else {
-                this.$Message.info(this.$t('schoolBaseInfo.ssTips7'))
-            }
+            this.addSemStatus = true
+            // let semLen = this.schoolSetting.period[this.curPriodIndex].semesters.length
+            // if (semLen < this.TERM_MAX_LENGTH) {
+            //     let defMonth = semLen == 0 ? 1 : this.schoolSetting.period[this.curPriodIndex].semesters[semLen - 1].month + 1
+            //     this.schoolSetting.period[this.curPriodIndex].semesters.push({
+            //         name: this.$t('schoolBaseInfo.persetSemester') + (this.schoolSetting.period[this.curPriodIndex].semesters.length + 1),
+            //         month: defMonth,
+            //         day: 26,
+            //         id: this.guid()
+            //     })
+            //     this.countSemDays()
+            //     this.$nextTick(() => {
+            //         setTimeout(() => {
+            //             this.curSemIndex = this.schoolSetting.period[this.curPriodIndex].semesters.length - 1
+            //             this.editSemIndex = this.curSemIndex
+            //         }, 200)
+            //     })
+            // } else {
+            //     this.$Message.info(this.$t('schoolBaseInfo.ssTips7'))
+            // }
         },
         getLocalDefaultData() {
             let data = require('@/static/baseDataDefault.json')

+ 462 - 0
TEAMModelOS/ClientApp/src/view/student-account/ClassMgt.less

@@ -0,0 +1,462 @@
+@main-bgColor: rgb(40,40,40); //主背景颜色
+@borderColor: #424242; //边框颜色
+@primary-textColor: #fff; //文本主颜色
+@second-textColor: #a5a5a5; //文本副级颜色
+@third-textColor: #dddddd;//其他颜色
+@fourth-textColor: #1cc0f3;
+@primary-fontSize: 14px;
+@second-fontSize: 16px;
+@large-fontSize: 20px;
+.class-mgt-container {
+    height: 100%;
+    width: 100%;
+    display: flex;
+    flex-direction: row;
+
+    .class-list-wrap {
+        width: 400px;
+        height: 100%;
+        border-right: 1px solid @borderColor;
+    }
+
+    .class-info-wrap {
+        width: ~"calc(100% - 400px)";
+        height: 100%;
+        padding-left:15px;
+    }
+}
+.class-list-header{
+    width:100%;
+    height:45px;
+    line-height:45px;
+    border-bottom:1px solid @borderColor;
+    padding-left:15px;
+    color:@second-textColor;
+}
+.action-btn {
+    float: right;
+    display: flex;
+    align-items: center;
+    margin-right: 15px;
+    &-icon {
+        color: white;
+        font-size: 16px;
+        margin-right: 12px;
+        margin-left: 10px;
+        cursor: pointer;
+
+        &.hide-icon {
+            display: none;
+        }
+    }
+}
+.class-info-header{
+    width:100%;
+    height:45px;
+    line-height:45px;
+    border-bottom:1px solid @borderColor;
+}
+.class-info-content{
+    width:100%;
+    height:~"calc(100% - 45px)";
+    position:relative;
+}
+.main-header-tab {
+    color: @second-textColor;
+    margin-right: 15px;
+    cursor: pointer;
+    position: relative;
+    display: inline-block;
+    line-height: 25px;
+}
+
+.border(right) {
+    border-right: 1px solid @borderColor;
+}
+.border(top) {
+    border-top: 1px solid @borderColor;
+}
+.border(left) {
+    border-left: 1px solid @borderColor;
+}
+.border(bottom) {
+    border-bottom: 1px solid @borderColor;
+}
+.container-left {
+    width: 59%;
+    height:100%;
+    .border(right);
+
+    &-title {
+        width: 100%;
+        padding-left: 15px;
+        height: 50px;
+        .border(bottom);
+        line-height: 50px;
+        padding-right: 35px;
+    }
+}
+.container-right {
+    width: 41%;
+    height:100%;
+
+    &-title {
+        width: 100%;
+        height: 45px;
+        line-height: 45px;
+        .border(bottom);
+    }
+}
+.first-title {
+    font-size: @primary-fontSize + 1;
+    color: @second-textColor;
+    font-weight:900;
+}
+
+.label-style {
+    font-size: @primary-fontSize - 1;
+    color: @second-textColor;
+    float: right;
+    margin-right: 40px;
+    cursor: pointer;
+}
+.label-style .label-icon{
+    margin-right:15px;
+}
+.save-btn {
+    margin-top: 5px;
+    /*color: black;*/
+    float: right;
+    margin-right: 30px;
+}
+.school-plan-wrap {
+    height: 100%;
+    width: 100%;
+    display: flex;
+    flex-flow: row;
+    align-items: center;
+    justify-content: center;
+}
+.school-plan-wrap p{
+    position:absolute;
+    top:0px;
+    right:0px;
+    padding:8px 35px 6px 20px;
+    .border(bottom);
+    color:white;
+    cursor:pointer;
+}
+.school-plan-wrap .label-icon {
+    margin-right: 15px;
+
+}
+.container-left-wrap{
+    width:100%;
+    height:~"calc(100% - 50px)";
+    display:flex;
+    flex-direction:row;
+}
+.container-left-box {
+    width: 38%;
+    height: 100%;
+    .border(right);
+    
+    .list-order {
+        padding: 5px 0px 5px 15px;
+        color: white;
+
+        .label-icon {
+            margin-right: 10px;
+        }
+    }
+}
+.container-right-box {
+    width: 62%;
+    height: 100%;
+    padding-left:15px;
+}
+.class-search-input{
+    width:~"calc(100% - 15px)";
+    margin-left:10px;
+    height:45px;
+    line-height:45px;
+}
+.class-list {
+    width: 100%;
+    height:~"calc(100% - 50px)";
+    padding-left: 15px;
+    
+}
+.active-item-bg {
+    background-image: linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
+}
+.class-list-item {
+    padding: 8px 0px;
+    .border(bottom);
+    cursor:pointer;
+    position:relative;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;    
+    &:hover {
+        .active-item-bg,
+        .period-btn-edit {
+            display: inline-block;
+        }
+    }
+}
+.class-name {
+    font-size: @large-fontSize;
+    color: white;
+    font-weight: 500;
+}
+.second-text-color {
+    color: @second-textColor;
+    font-size: 12px;
+}
+.third-text-color{
+    color:@third-textColor;
+}
+.fourth-text-color {
+    color: #1cc0f3 !important;
+    /*text-shadow:1px 1px 1px white;*/
+}
+.class-hiteach-code {
+    margin-top:5px;
+}
+.class-type {
+    margin-top:6px;
+    margin-bottom:4px;
+    align-items: center;
+    display: flex;
+    span{
+        color: rgb(28, 192, 243);
+    }
+}
+.iconHi{
+    display: inline-block;
+    margin-right: 5px;
+    width: 14px;
+    height: 14px;
+}
+.iconBoard {
+    width: 14px;
+    height: 14px;
+    background: rgb(165, 165, 165);
+    border-radius: 16%;
+    display: inline-flex;
+    justify-content: center;
+    align-items: center;
+    margin-right: 5px;
+}
+.primary-text-color{
+    color:@primary-textColor;
+}
+
+.class-attr-wrap{
+    width:35%;
+    height:100%;
+    .border(right);
+    &-label{
+        display:inline-block;
+        color:@second-textColor;
+        font-size:@second-fontSize - 4px;
+    }
+}
+.hiteach-code-wrap {
+    width: 100%;
+    height: 100%;
+    position: relative;
+    &-header {
+        width: ~"calc(100% - 30px)";
+        margin-left: 20px;
+
+        p {
+            padding: 10px 0px;
+            color: @second-textColor;
+            .border(bottom);
+        }
+    }
+
+    &-list {
+        .border(top);
+        width: 100%;
+        height: ~"calc(100% - 72px)";
+        padding-left: 25px;
+        h1 {
+            font-weight: 400;
+        }
+
+        ul {
+            list-style: none;
+
+            li {
+                color: #dbdbdb;
+                display: flex;
+                align-items: center;
+                margin-bottom: 5px;
+            }
+        }
+    }
+}
+#school-plan {
+    background: none;
+}
+.school-plan-zoom {
+    position: absolute;
+    right: 150px;
+    top: 10px;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    .ivu-icon {
+        margin-right: 10px;
+        cursor: pointer;
+    }
+
+    span {
+        color: white;
+        font-size: 16px;
+        margin-right: 15px;
+        display: inline-block;
+        letter-spacing: 3px;
+        cursor: pointer;
+    }
+}
+.school-plan-box {
+    width: ~"calc(100% - 60px)";
+    max-height: 90%;
+    overflow: scroll;
+    text-align: center;
+
+    &::-webkit-scrollbar { /*滚动条整体样式*/
+        width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
+        height: 8px;
+    }
+
+    &::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
+        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
+        background: rgb(124,124,124);
+    }
+
+    &::-webkit-scrollbar-track { /*滚动条里面轨道*/
+        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
+        background: rgba(68,68,68,.5);
+    }
+}
+.hiteach-collapse{
+    border-bottom: 1px solid #424242;
+    position: relative;
+    cursor: pointer;
+    &-main{
+        display: flex;
+        align-items: center;
+        padding: 20px 0 20px 20px;
+        &:hover{
+            background-image: linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
+        }
+        .arrowIcon{
+            position: absolute;
+            right: 5px;
+            top: 20px;
+        }
+        .proIcon{
+            width: 60px;
+            height: 60px;
+            margin-right: 30px;
+        }
+        .proCont{
+            font-size: 12px;
+            letter-spacing: 1px;
+            ul li{
+                .title{
+                    display: inline-block;
+                    margin-right: 12px;
+                    font-size: 16px;
+                    font-weight: 500;
+                    color: #bdbdbd;
+                    color:white;
+                }
+                .serialType{
+                    margin-right: 12px;
+                    padding: 2px 5px;
+                    background: #1cc0f3;
+                    border-radius: 3px;
+                    color: white;
+                }
+                .tag{
+                    display: inline-block;
+                    border: 1px solid #8d8d8d;
+                    padding: 3px 10px;
+                    color: #8d8d8d;
+                    margin-top: 5px;
+                    margin-right: 10px;
+                    border-radius: 5px;
+                    &.active{
+                        color: #1cc0f3!important;
+                        border-color: #1cc0f3!important;
+                    }
+                }
+            }
+        }
+    }
+    .hiteach-collapse-sub{
+        display: flex;
+        align-items: center;
+        border-top: 1px solid rgb(66, 66, 66);
+        margin-left: 20px;
+        letter-spacing: 1px;
+        font-size: 12px;
+        padding: 20px;        
+        &:hover{
+            background-image: linear-gradient(90deg, #2a2a2e, #293942);
+        }
+        &-detail{
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            width: 100%;
+        }
+        &.linked{
+            ul li{
+                color: #888888;
+            }            
+            cursor: not-allowed;
+        }
+        &-linkBtn{
+            cursor: pointer;
+            border-radius: 5px;
+            padding: 5px 12px;
+            font-size: 12px;
+            background-color: #1cc0f3;
+            color: white;
+            text-align: center;
+            font-weight: 700;
+            margin-right: 70px;
+            border-color: transparent;
+            &:hover{
+                background-color: #0ba2d1;
+            }
+        }
+    }
+}
+
+.class-id-tag {
+    color: aqua;
+    font-size: 14px;
+    margin-right: 5px;
+    border: 1px solid aqua;
+    padding: 1px 3px;
+    border-radius: 3px;
+    vertical-align:middle;
+}
+.item-tools{
+    display:none;
+}
+
+.reset-no-btn{
+    display: inline-block;
+    margin-left: 10px;
+    cursor: pointer;
+}

+ 867 - 0
TEAMModelOS/ClientApp/src/view/student-account/ClassMgt.vue

@@ -0,0 +1,867 @@
+<template>
+    <div class="class-mgt-container">
+        <Loading v-show="isListLoading"></Loading>
+        <div class="class-list-wrap">
+            <!--班级列表-->
+            <div class="class-list-header">
+                <Dropdown class="sort-dropdown" trigger="click" placement="bottom-start" @on-click="function(e){ filterPeriod = e }" @on-visible-change="dropdownStates" v-if="$store.state.user.schoolProfile.school_base">
+                    <span style="cursor: pointer;">
+                        <!-- {{$t('schoolBaseInfo.pdLabel')}} -->
+                        <b class="title">{{ filterPeriodName }}</b>
+                        <Icon type="ios-arrow-down" style="margin-left:8px;"></Icon>
+                    </span>
+                    <DropdownMenu slot="list" v-for="(item,index) in periods" :value="item.id" :key="index">
+                        <DropdownItem :name="item.id">{{ item.name }}</DropdownItem>
+                    </DropdownMenu>
+                </Dropdown>
+                <Dropdown class="sort-dropdown" trigger="click" placement="bottom-start" @on-click="function(e){ filterYear = e.value }" style="margin-left:15px">
+                    <span style="cursor: pointer;">
+                        <!-- {{$t('schoolBaseInfo.pdLabel')}} -->
+                        <b class="title">{{ filterYear + '级' }}</b>
+                        <Icon type="ios-arrow-down" style="margin-left:8px;"></Icon>
+                    </span>
+                    <DropdownMenu slot="list" v-for="(item,index) in years" :value="item.value" :key="index">
+                        <DropdownItem :name="item.label">{{ item.label }}</DropdownItem>
+                    </DropdownMenu>
+                </Dropdown>
+                <div v-if="!isSearch" style="float:right;">
+                    <Icon class="action-btn-icon" type="ios-search" @click="isSearch = true" />
+                    <Icon v-if="$access.can('admin.*|classroom-upd')" class="action-btn-icon" type="md-trash" @click.stop="showConfirmDelete()" />
+                    <Icon v-if="$access.can('admin.*|classroom-upd')" class="action-btn-icon" type="md-add" @click="addClassroom()" />
+                </div>
+                <div v-else class="dark-iview-input" style="float:right;width:calc(100% - 180px);padding-right:10px;">
+                    <Input icon="ios-close" v-model="keyword" :placeholder="$t('schoolBaseInfo.codeSearchHolder')" autofocus style="width:100%" @on-click="closeKeySearch" @on-change="filterClassname" />
+                </div>
+            </div>
+            <div class="class-list">
+                <vuescroll>
+                    <div class="class-list-item" v-for="(item,index) in classroomListShow" :key="index" @click="chooseClassroom(index)" :class="curClassIndex == index ? 'block-bg block-bg-active':'block-bg'">
+                        <div class="class-list-item-left">
+                            <!-- <p style="color: #a5a5a5;">{{$jsFn.getGradeName(schoolBase,item.gradeId)}}</p> -->
+                            <p style="color: #a5a5a5;">2020级</p>
+                            <p class="class-name">
+                                <span class="class-id-tag">
+                                    {{item.no}}
+                                </span>
+                                <span>
+                                    {{item.name}}
+                                </span>
+                            </p>
+                            <p class="class-type">
+                            <p class="second-text-color">
+                                <span>{{ $t('schoolBaseInfo.headmaster') }}</span>
+                                <span class="primary-text-color">{{item.teacher.name}}</span>
+                                <span style="margin-left:15px">学生人数:</span>
+                                <span class="primary-text-color">40人</span>
+                            </p>
+                        </div>
+                    </div>
+                    <EmptyData v-if="classroomListShow.length == 0" style="padding-top:120px;"></EmptyData>
+                </vuescroll>
+            </div>
+        </div>
+        <div class="class-info-wrap">
+            <div class="class-info-header common-save-btn">
+                <span :class="currentTabIndex == 0 ? 'main-header-tab line-bottom line-bottom-active':'main-header-tab line-bottom'" @click="selectTab(0)">
+                    {{$t('schoolBaseInfo.tab1')}}
+                </span>
+                <span :class="currentTabIndex == 2 ? 'main-header-tab line-bottom line-bottom-active':'main-header-tab line-bottom'" @click="selectTab(2)">
+                    {{$t('schoolBaseInfo.tab2')}}
+                </span>
+                <!-- 编辑教室 -->
+                <Button v-if="$access.can('admin.*|classroom-upd')" class="save-btn" :loading="isSaveLoading" :disabled="!updated" icon="ios-albums-outline" @click="saveClassroom()" v-show="currentTabIndex == 0">
+                    {{$t('schoolBaseInfo.saveInfo')}}
+                </Button>
+                <!-- 添加学生 -->
+                <Button v-if="$access.can('admin.*|student-upd')" class="save-btn" :loading="isSaveLoading" icon="md-add" @click="addStuStatus = true" v-show="currentTabIndex == 2">
+                    {{$t('schoolBaseInfo.addStuBtn')}}
+                </Button>
+                <!-- 移除学生 -->
+                <Button v-if="$access.can('admin.*|student-upd')" class="save-btn" style="margin-right:10px;" :loading="isSaveLoading" icon="md-remove-circle" @click="removeStudent(-1)" v-show="currentTabIndex == 2">
+                    {{$t('schoolBaseInfo.delStuBtn')}}
+                </Button>
+            </div>
+            <div class="class-info-content">
+                <!--基础信息-->
+                <div v-show="currentTabIndex == 0" style="display:flex;flex-direction:row;width:100%;height:100%;">
+                    <!--班级属性-->
+                    <div class="class-attr-wrap disabled-iview-select dark-iview-select">
+                        <vuescroll>
+                            <Form v-if="classroomListShow[curClassIndex]" ref="classInfo" :model="classroomListShow[curClassIndex]" :rules="classValidate" style="padding-top:20px;">
+                                <FormItem prop="name" :label="$t('schoolBaseInfo.classroomName')" @click.native.stop class="requird-color">
+                                    <span slot="label" class="class-attr-wrap-label">名称</span>
+                                    <Input @on-change="watchUpdate" :disabled="editStatus" v-model="classroomListShow[curClassIndex].name" clearable :placeholder="$t('schoolBaseInfo.classroomNameHolder')" />
+                                </FormItem>
+                                <FormItem prop="no" @click.native.stop class="requird-color">
+                                    <span slot="label" class="class-attr-wrap-label">编码</span>
+                                    <Input @on-change="watchUpdate" :disabled="editStatus" v-model="classroomListShow[curClassIndex].no" clearable :placeholder="$t('schoolBaseInfo.classroomCodeHolder')" />
+                                </FormItem>
+                                <FormItem prop="gradeId" :label="$t('schoolBaseInfo.setGrade')" @click.native.stop class="requird-color">
+                                    <span slot="label" class="class-attr-wrap-label">学级</span>
+                                    <Select @on-change="watchUpdate" :disabled="editStatus" v-model="classroomListShow[curClassIndex].gradeId" clearable>
+                                        <Option v-for="(item,index) in $jsFn.getPeriod($store.state.user.schoolProfile.school_base,classroomListShow[curClassIndex].periodId).grades" :value="item.id" :key="index">
+                                            {{ item.name }}
+                                        </Option>
+                                    </Select>
+                                </FormItem>
+                                <FormItem prop="teacher" :label="$t('schoolBaseInfo.headmaster')" @click.native.stop class="requird-color">
+                                    <span slot="label" class="class-attr-wrap-label">{{$t('schoolBaseInfo.headmaster')}}</span>
+                                    <Select @on-change="watchUpdate" :disabled="editStatus" v-model="classroomListShow[curClassIndex].teacher.id" clearable filterable>
+                                        <Option v-for="(item,index) in $store.state.teachers.teacherList.filter(item=>item.status == 'join')" :value="item.id" :key="index" @click.native="classroomListShow[curClassIndex].teacher = {id:item.id, name:item.name}">
+                                            {{ item.name }}
+                                        </Option>
+                                    </Select>
+                                </FormItem>
+                                <FormItem prop="profession" @click.native.stop class="requird-color">
+                                    <span slot="label" class="class-attr-wrap-label">专业</span>
+                                    <Select @on-change="watchUpdate" :disabled="editStatus" v-model="classroomListShow[curClassIndex].marjorId" clearable not-found-text="暂未设置专业">
+                                        <Option v-for="(item,index) in $jsFn.getPeriod($store.state.user.schoolProfile.school_base,classroomListShow[curClassIndex].periodId).majors" :value="item.id" :key="index">
+                                            {{ item.name }}
+                                        </Option>
+                                    </Select>
+                                </FormItem>
+                                <FormItem prop="profession" @click.native.stop class="requird-color">
+                                    <span slot="label" class="class-attr-wrap-label">默认教室</span>
+                                    <Select @on-change="watchUpdate" :disabled="editStatus" v-model="classroomListShow[curClassIndex].roomId" clearable not-found-text="暂无教室">
+                                        <Option v-for="(item,index) in $jsFn.getPeriod($store.state.user.schoolProfile.school_base,classroomListShow[curClassIndex].periodId).majors" :value="item.id" :key="index">
+                                            {{ item.name }}
+                                        </Option>
+                                    </Select>
+                                </FormItem>
+                            </Form>
+                        </vuescroll>
+                    </div>
+                </div>
+
+                <!--学生名单-->
+                <div id="sut-list-box" class="dark-iview-table dark-iview-input" style="width:100%;height:100%;" v-show="currentTabIndex == 2">
+                    <vuescroll style="height:100%;" v-if="classroomListShow[curClassIndex]">
+                        <Table :columns="studentColumn" :data="students" @on-selection-change="(selections)=>{delSelections = selections}" :height="tableHeight" class="system-classroom-table" :loading="stuLoading" :no-data-text="$t('schoolBaseInfo.noStu')">
+                            <Loading slot="loading" :top="0" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
+                            <template slot-scope="{ row }" slot="picture">
+                                <PersonalPhoto :name="row.name" :picture="row.picture" />
+                            </template>
+                            <template slot-scope="{ row,index }" slot="no">
+                                <span v-show="editIndex !== index">{{row.no}}</span>
+                                <Input v-model="students[index].no" v-show="editIndex == index" style="width: 60px;" type="number" />
+                                <Icon type="md-checkmark" v-show="editIndex == index" @click="confirmSetNo()" class="reset-no-btn" />
+                                <Icon type="md-close" v-show="editIndex == index" @click="cancelSetNo()" class="reset-no-btn" />
+                            </template>
+                            <template slot-scope="{ row ,index}" slot="action">
+                                <div class="item-tools" v-if="$access.can('admin.*|student-upd')">
+                                    <Icon type="md-create" size="18" color="white" @click="resetNo(index)" :title="$t('schoolBaseInfo.editSeat')" />
+                                    <Icon type="md-remove-circle" size="18" color="white" style="margin-left:10px" @click="removeStudent(index)" :title="$t('schoolBaseInfo.delStuBtn')" />
+                                </div>
+                            </template>
+                        </Table>
+                    </vuescroll>
+                </div>
+            </div>
+        </div>
+        <Modal v-model="addStuStatus" :title="$t('schoolBaseInfo.addStuBtn')" width="1200" @on-ok="confirmAddStu" class-name="dark-iview-modal">
+            <StudentList @getSelectInfo="(selction)=>{selections = selction}"></StudentList>
+        </Modal>
+    </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import PersonalPhoto from "@/components/public/personalPhoto/Index.vue"
+import StudentList from '@/components/coursemgt/StudentList.vue'
+export default {
+    components: {
+        PersonalPhoto, StudentList
+    },
+    data() {
+        // 验证只能是字母和数字
+        const validateCode = (rule, value, callback) => {
+            if (!value) {
+                return callback(new Error(this.$t('schoolBaseInfo.classNoErr')))
+            }
+            let zg = /^[0-9a-zA-Z]+$/
+            if (zg.test(value)) {
+                callback()
+            } else {
+                callback(new Error(this.$t('schoolBaseInfo.classNoErr1')))
+            }
+        }
+        return {
+            filterYear:'2021',
+
+            // years:[2021,2020,2019,2018,2017,2016,2015,2014],
+            studentColumn: [
+                {
+                    title: ' ',
+                    type: 'selection',
+                    width: 60,
+                    align: 'center'
+                },
+                {
+                    title: ' ',
+                    slot: 'picture',
+                    align: 'center ',
+                    width: '150'
+                },
+                {
+                    title: this.$t('courseManage.classroom.studentTableC2'),
+                    key: 'name',
+                    align: 'center '
+                },
+                {
+                    title: this.$t('courseManage.classroom.studentTableC7'),
+                    key: 'id',
+                    align: 'center',
+                    sortable: true
+                },
+                {
+                    title: this.$t('courseManage.classroom.studentTableC1'),
+                    slot: 'no',
+                    align: 'center',
+                    sortable: true
+                },
+                {
+                    title: ' ',
+                    slot: 'action',
+                    align: 'center',
+                    width: '150'
+                }
+            ],
+            editIndex: -1,
+            resetNoBef: 0,
+            schoolBase: {
+                period: []
+            },
+            delSelections: [],//需要移除的学生
+            selections: [],//添加的学生
+            addStuStatus: false,
+            stuLoading: false,
+            orderBy: 'id',
+            updateBefore: '',
+            filterPeriod: undefined,
+            editStatus: true,//可切换编辑状态
+            noStatus: false,
+            isSearch: false,
+            currentTabIndex: 0,
+            isListLoading: false,
+            isSaveLoading: false,
+            isInit: true,
+            updated: false,
+            classroomList: [],
+            classroomListShow: [],
+            curClassIndex: 0,
+            keyword: '',
+            serchCode: '',
+            attributeList: [
+                {
+                    value: '1',
+                    label: this.$t('schoolBaseInfo.classAttr1')
+                },
+                {
+                    value: '2',
+                    label: this.$t('schoolBaseInfo.classAttr2')
+                }
+            ],
+            classValidate: {
+                no: [
+                    { required: true, validator: validateCode, trigger: 'change' }
+                ],
+                name: [
+                    { required: true, message: this.$t('schoolBaseInfo.nameWarning'), trigger: 'change' }
+                ],
+                openType: [
+                    { required: true, message: this.$t('schoolBaseInfo.typeWarning'), trigger: 'change' }
+                ],
+                gradeId: [
+                    { required: true, message: this.$t('schoolBaseInfo.gradeWarning'), trigger: 'change' }
+                ]
+            }
+        }
+    },
+    computed: {
+        ...mapGetters({
+            periods: 'user/getPeriods', // 學制s
+        }),
+        filterPeriodName: function () {
+            let data = this.periods
+            let pId = this.filterPeriod
+            let name = ''
+            if (pId !== '') {
+                let temp = data.filter(item => {
+                    return pId == item.id
+                })
+                if (temp.length > 0) name = temp[0].name
+            }
+            return name
+        },
+
+        students() {
+            if (this.currentTabIndex == '2') {
+                if (this.classroomListShow[this.curClassIndex] && this.classroomListShow[this.curClassIndex].students) {
+                    return this.classroomListShow[this.curClassIndex].students
+                } else {
+                    let params = {
+                        'school_code': this.$store.state.userInfo.schoolCode,
+                        'ids': [this.classroomListShow[this.curClassIndex].id],
+                        'scope': 'school'
+                    }
+                    this.stuLoading = true
+                    this.$api.schoolSetting.getClassroomStudent(params).then(
+                        res => {
+                            if (res.stus.length > 0) {
+                                this.$set(this.classroomListShow[this.curClassIndex], 'students', res.stus[0])
+                            }
+                        },
+                        err => {
+                            this.$Message.error(this.$t('schoolBaseInfo.findStuErr'))
+                        }
+                    ).finally(() => {
+                        this.stuLoading = false
+                    })
+                }
+            } else {
+                return []
+            }
+        },
+
+        years(){
+            if(this.schoolBase && this.schoolBase.period.length && this.filterPeriod){
+                let pData = this.schoolBase.period.find(item=>{
+                    return item.id == this.filterPeriod
+                })
+                if(pData){
+                    let year = (new Date()).getFullYear()
+                    console.log(pData)
+                    let res = pData.grades.map(item=>{
+                        return {
+                            label:`${item.name}(${year}级)`,
+                            value:year--
+                        }
+                    })
+                    return res
+                }else{
+                    return []
+                }
+            }
+            return []
+        }
+    },
+    methods: {
+        resetNo(index) {
+            this.editIndex = index
+            this.resetNoBef = this.students[index].no
+        },
+        confirmSetNo() {
+            this.$Message.warning('暂未对接API')
+            this.editIndex = -1
+        },
+        cancelSetNo() {
+            this.students[this.editIndex].no = this.resetNoBef
+            this.editIndex = -1
+        },
+        //移除班级里面的学生
+        removeStudent(index) {
+            let requestParams = {
+                schoolId: this.$store.state.userInfo.schoolCode,
+                students: [],
+                grant_type: 'remove'
+            }
+            let names = []
+            if (index > -1) {
+                requestParams.students.push(this.students[index].id)
+                names = [this.students[index].name]
+            } else if (this.delSelections.length > 0) {
+                requestParams.students = this.delSelections.map(item => {
+                    return item.id
+                })
+                names = this.delSelections.map(item => {
+                    return item.name
+                })
+            }
+            if (requestParams.students.length) {
+                this.$Modal.confirm({
+                    title: this.$t('schoolBaseInfo.removeTile'),
+                    content: `${this.$t('schoolBaseInfo.removeContent')}${names.join(', ')}?`,
+                    onOk: () => {
+                        this.$api.stuAccount.removeStudent(requestParams).then(
+                            res => {
+                                this.$Message.success(this.$t('schoolBaseInfo.removeOk'))
+                                if (index > -1) {
+                                    this.students.splice(index, 1)
+                                } else {
+                                    for (let i = 0; i < this.students.length; i) {
+                                        if (requestParams.students.indexOf(this.students[i].id) > -1) {
+                                            this.students.splice(i, 1)
+                                            i--
+                                        }
+
+                                    }
+                                    this.students.forEach()
+                                }
+                            },
+                            err => {
+                                this.$Message.error(this.$t('schoolBaseInfo.removeErr'))
+                            }
+                        )
+                    }
+                })
+            }
+        },
+        //确认添加学生
+        confirmAddStu() {
+            if (this.selections.length > 0) {
+                console.log(this.selections)
+                let data = this._.cloneDeep(this.selections)
+                data.forEach(item => {
+                    item.classId = this.classroomListShow[this.curClassIndex].id
+                    item.className = this.classroomListShow[this.curClassIndex].name
+                    item.classNo = this.classroomListShow[this.curClassIndex].no
+                })
+
+                this.listLoading = true
+                this.$api.stuAccount.updateStudent({
+                    students: data,
+                    grant_type: 'update',
+                    schoolId: this.$store.state.userInfo.schoolCode
+                }).then(
+                    (res) => {
+                        if (!res.error) {
+                            this.selections.length = 0
+                            this.students.push(...data)
+                            this.$Message.success(this.$t('schoolBaseInfo.addOk'))
+                        } else {
+                            this.$Message.error(this.$t('schoolBaseInfo.addErr'))
+                        }
+                    },
+                    (err) => {
+                        this.$Message.error(this.$t('schoolBaseInfo.addErr'))
+                    }
+                ).finally(() => {
+                    this.listLoading = false
+                    this.baseEditStatus = !this.baseEditStatus
+                })
+            }
+        },
+
+        dropdownStates(flag) {
+            if (!flag) this.filterByPeriod()
+        },
+        restOrderBy(flag) {
+            if (!flag) this.filterByPeriod()
+        },
+        closeKeySearch() {
+            this.isSearch = false
+            this.keyword = ''
+            this.filterClassname()
+        },
+        watchUpdate(data) {
+            if (data) {
+                this.updated = true
+            }
+        },
+        dataSort(data) {
+            switch (this.orderBy) {
+                case 'id': // no=>编号 排序
+                    data.sort(function (a, b) {
+                        let nameA = a.no.toUpperCase(); // ignore upper and lowercase
+                        let nameB = b.no.toUpperCase(); // ignore upper and lowercase
+                        if (nameA < nameB) {
+                            return -1;
+                        }
+                        if (nameA > nameB) {
+                            return 1;
+                        }
+
+                        // names must be equal
+                        return 0;
+                    })
+                    break;
+                case 'total':
+                    data.sort(function (a, b) {
+                        return b.studCount - a.studCount;
+                    })
+                    break;
+            }
+            return data
+        },
+        filterByPeriod() {
+            this.curClassIndex = 0
+            if (this.filterPeriod) {
+                this.classroomListShow = this.classroomList.filter(item => item.periodId == this.filterPeriod || !item.periodId)
+            } else {
+                this.classroomListShow = [...this.classroomList]
+            }
+            // 排序
+            this.classroomListShow = this.dataSort(this.classroomListShow)
+
+        },
+        filterClassname() {
+            if (this.keyword == '' || this.keyword == undefined) {
+                this.filterByPeriod()
+            } else {
+                let filterRes = []
+                if (this.filterPeriod) {
+                    filterRes = this.classroomList.filter(item => item.periodId == this.filterPeriod)
+                } else {
+                    filterRes = [...this.classroomList]
+                }
+                this.classroomListShow = filterRes.filter(item => item.name.indexOf(this.keyword) != -1)
+                // 排序
+                this.classroomListShow = this.dataSort(this.classroomListShow)
+                this.curClassIndex = 0
+                this.updateBefore = JSON.stringify(this.classroomListShow[this.curClassIndex])
+            }
+        },
+        selectTab(index) {
+            this.currentTabIndex = index
+        },
+        saveClassroom() {
+            this.$refs['classInfo'].validate((valid) => {
+                if (!valid) {
+                    this.$Message.error(this.$t('schoolBaseInfo.formWarning'))
+                } else {
+                    let option = this.classroomListShow[this.curClassIndex].option
+                    if (!option) {
+                        option = 'update'
+                    } else {
+                        this.classroomListShow[this.curClassIndex]['code'] = this.$store.state.userInfo.schoolCode
+                    }
+                    delete this.classroomListShow[this.curClassIndex].option
+                    this.isSaveLoading = true
+                    this.isListLoading = true
+                    if (this.classroomListShow[this.curClassIndex].openType == '2') {
+                        this.classroomListShow[this.curClassIndex].teacher.id = ''
+                        this.classroomListShow[this.curClassIndex].teacher.name = ''
+                    }
+                    this.$api.schoolSetting.classUpsert({
+                        classroom: this.classroomListShow[this.curClassIndex],
+                        option: option,
+                        school_code: this.$store.state.userInfo.schoolCode
+                    }).then(
+                        res => {
+                            if (res) {
+                                if (res.error) {
+                                    this.classroomListShow[this.curClassIndex].option = option
+                                    this.$Message.error(res.v)
+                                } else {
+                                    this.$Message.success(this.$t('schoolBaseInfo.csTips3'))
+                                    this.updated = false
+                                    if (option == 'insert') {
+                                        this.classroomListShow[this.curClassIndex].code = 'Class-' + this.classroomListShow[this.curClassIndex].code
+                                        this.classroomList.unshift(this.classroomListShow[this.curClassIndex])
+                                        this.$store.dispatch('user/addSchoolClasses', this.classroomListShow[this.curClassIndex]);
+                                    }
+                                }
+                            } else {
+                                this.$Message.error('API error!')
+                            }
+                        },
+                        err => {
+                            this.$Message.error('API error!')
+                        }
+                    ).finally(
+                        () => {
+                            this.isSaveLoading = false
+                            this.isListLoading = false
+                        }
+                    )
+                }
+            })
+        },
+        getClassroom() {
+            this.isListLoading = true
+            this.$store.dispatch('user/getSchoolProfile').then(
+                (res) => {
+                    if (res) {
+                        this.classroomList = res.school_classes
+                        this.schoolBase = res.school_base
+                        if (this.classroomList.length > 0) {
+                            this.updateBefore = JSON.stringify(this.classroomList[0])
+                        }
+                        this.filterClassname()
+                        // 預設搜尋給第一個
+                        if (this.periods) this.filterPeriod = this.periods[0].id
+                        this.filterByPeriod()
+                    }
+                },
+                (err) => {
+                    this.$Message.error('API error!')
+                }
+            ).finally(() => {
+                setTimeout(() => {
+                    this.isListLoading = false
+                }, 500)
+            })
+        },
+        /**显示确认删除班级对话框 */
+        showConfirmDelete() {
+            if (this.$access.can('admin.*|classroom-upd')) {
+                this.$Modal.confirm({
+                    title: this.$t('schoolBaseInfo.delClass'),
+                    content: this.$t('schoolBaseInfo.delete') + this.classroomListShow[this.curClassIndex].name + this.$t('schoolBaseInfo.delContent'),
+                    onOk: () => {
+                        this.delClassroom(this.curClassIndex)
+                    }
+                })
+            } else {
+                this.$Message.warning(this.$t('schoolBaseInfo.authWarning'))
+            }
+        },
+        delClassroom(index) {
+            this.isListLoading = true
+            if (this.classroomListShow[index].option !== 'insert') {
+                this.$api.schoolSetting.delClassroom({
+                    id: this.classroomListShow[index].id,
+                    scope: this.classroomListShow[index].scope,
+                    school_code: this.$store.state.userInfo.schoolCode
+                }).then(
+                    (res) => {
+                        if (res.error == null) {
+                            if (this.curClassIndex >= index && index > 0) {
+                                this.curClassIndex = 0
+                                this.updateBefore = JSON.stringify(this.classroomListShow[this.curClassIndex])
+                            }
+                            let originIndex = -1
+                            for (let i in this.classroomList) {
+                                if (this.classroomList[i].id == this.classroomListShow[index].id) {
+                                    originIndex = i
+                                    break
+                                }
+                            }
+                            this.$api.schoolSetting.hiteachUnlinkByClassId({
+                                classId: this.classroomListShow[index].id,
+                                school_code: this.$store.state.userInfo.schoolCode
+                            })                             
+                            this.$store.dispatch('user/delSchoolClasses', this.classroomListShow[index].id);
+                            this.classroomList.splice(originIndex, 1)
+                            this.classroomListShow.splice(index, 1)
+                            this.$Message.success(this.$t('schoolBaseInfo.csTips7'))
+                            this.updated = false
+                        }
+                    },
+                    (err) => {
+                        this.$Message.error('API error!')
+                    }
+                ).finally(() => {
+                    this.isListLoading = false
+                })
+            } else {
+                if (this.curClassIndex >= index && index > 0) {
+                    this.curClassIndex = 0
+                    this.updateBefore = JSON.stringify(this.classroomListShow[this.curClassIndex])
+                }
+                this.classroomListShow.splice(index, 1)
+                this.isListLoading = false
+                this.updated = false
+            }
+        },
+        chooseClassroom(index) {
+            if (index != this.curClassIndex) {
+                if (this.updated) {
+                    let config = {
+                        title: this.$t('schoolBaseInfo.saveWarning'),
+                        content: this.$t('schoolBaseInfo.saveClassWarning'),
+                        okText: this.$t('schoolBaseInfo.leaveText'),
+                        onOk: () => {
+                            if (this.classroomListShow[this.curClassIndex].option == 'insert') {
+                                this.delClassroom(this.curClassIndex)
+                            } else {
+                                this.updated = false
+                                this.$set(this.classroomListShow, this.curClassIndex, JSON.parse(this.updateBefore))
+                                this.curClassIndex = index
+                                this.updateBefore = JSON.stringify(this.classroomListShow[this.curClassIndex])
+                            }
+                        }
+                    }
+                    this.$Modal.confirm(config)
+                } else {
+                    this.curClassIndex = index
+                    this.updateBefore = JSON.stringify(this.classroomListShow[this.curClassIndex])
+                }
+            }
+        },
+        addClassroom() {
+            if (this.$access.can('admin.*|classroom-upd')) {
+                this.keyword = ''
+                this.classroomListShow.unshift({
+                    id: this.$jsFn.uuid(),
+                    name: this.$t('schoolBaseInfo.presetClassroomName') + (this.classroomList.length + 1),
+                    no: '',
+                    teacher: {
+                        id: '',
+                        name: ''
+                    },
+                    periodId: this.filterPeriod,
+                    gradeId: '',
+                    scope: 'school',
+                    option: 'insert'
+                })
+                this.curClassIndex = 0
+                this.updateBefore = JSON.stringify(this.classroomListShow[this.curClassIndex])
+            } else {
+                this.$Message.warning(this.$t('schoolBaseInfo.authWarning'))
+            }
+        },
+
+    },
+    mounted() {
+        this.filterClassname()
+        this.tableHeight = document.getElementById('class-mgt-list').clientHeight - 45
+    },
+    beforeRouteLeave(to, from, next) {
+        if (this.updated) {
+            let config = {
+                title: this.$t('schoolBaseInfo.saveWarning'),
+                content: this.$t('schoolBaseInfo.saveClassWarning'),
+                okText: this.$t('schoolBaseInfo.leaveText'),
+                onOk: () => {
+                    next()
+                },
+                onCancel: () => {
+                    next(false)
+                }
+            }
+            this.$Modal.confirm(config)
+        } else {
+            next()
+        }
+    },
+    created() {
+        this.$store.dispatch('user/getSchoolProfile').then(
+            res => {
+                this.schoolBase = res.school_base
+            }
+        )
+        if (this.$access.can('admin.*|classroom-upd')) this.editStatus = this.noStatus
+        this.getClassroom()
+        this.$store.dispatch('teachers/getTeacherList').then(res => { })
+    }
+}
+</script>
+<style lang="less" scoped>
+@import "./ClassMgt.less";
+</style>
+<style>
+.class-mgt-container .ivu-table-row-hover .item-tools {
+    display: inline-block;
+    cursor: pointer;
+}
+.class-info-content
+    .ivu-select-single
+    .ivu-select-selection
+    .ivu-select-placeholder,
+.class-info-content
+    .ivu-select-single
+    .ivu-select-selection
+    .ivu-select-selected-value {
+    color: white;
+}
+
+.class-search-input .ivu-input {
+    height: 30px;
+    background: none;
+    line-height: 30px;
+    border: none;
+    color: white;
+    font-size: 15px;
+}
+
+.class-attr-wrap .ivu-input {
+    width: calc(100% - 10px);
+    background: none;
+    border: none;
+    border-radius: 0px;
+    font-size: 16px;
+    color: white;
+    margin-left: 2px;
+    border-bottom: 1px solid #424242;
+}
+
+.class-attr-wrap .ivu-select {
+    width: calc(100% - 10px);
+    color: white;
+}
+
+.class-attr-wrap .ivu-select-selected-value {
+    font-size: 16px !important;
+}
+
+.class-attr-wrap .ivu-select-selection {
+    background: none;
+    border-color: #424242;
+}
+
+.class-attr-wrap .ivu-divider {
+    background-color: #424242;
+}
+
+</style>
+<style lang="less">
+.gradient {
+    @keyframes Itemfadein {
+        0% {
+            opacity: 0;
+            transform: translate(-40px);
+        }
+        100% {
+            opacity: 1;
+            transform: translate(0px);
+        }
+    }
+    animation: 0.5s Itemfadein;
+}
+
+.sort-dropdown {
+    .title {
+        color: white;
+        font-size: 14px;
+    }
+    .ivu-select-dropdown {
+        background-color: #2d2d2d;
+        border-radius: 2px;
+        border: 1px #464646 solid;
+        .ivu-dropdown-menu {
+            li {
+                color: #ccc;
+                font-size: 12px !important;
+                &:hover {
+                    color: #2d2d2d;
+                }
+            }
+        }
+    }
+}
+.requird-color {
+    .ivu-form-item-label:before {
+        color: #1cc0f3;
+    }
+}
+.hiteach-collapse {
+    //     background: transparent;
+    //     color: white;
+    //     border-top: none;
+    //     .ivu-collapse-item{
+    //         .ivu-collapse-header{
+    //             height: 200px;
+    //             line-height: 200px;
+    //             display: flex;
+    //             align-items: center;
+    //             padding-left: 15px;
+    .ivu-tag-border {
+        background: transparent !important;
+        margin-right: 10px;
+        border-radius: 5px;
+        letter-spacing: 1px;
+    }
+    //             .ivu-icon-ios-arrow-forward{
+    //                 position: absolute;
+    //                 right: 2px;
+    //                 font-size: 30px;
+    //                 color: white;
+    //             }
+    //         }
+    //         .ivu-collapse-content{
+    //             background: transparent;
+    //         }
+    //     }
+}
+</style>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/student-account/ImportStudent.vue

@@ -12,7 +12,7 @@
             </Upload>
             <p class="import-tips" style="margin-top:40px;">{{$t('stuAccount.importTips1')}}</p>
             <p class="import-tips">{{$t('stuAccount.importTips2') + $t('stuAccount.importTips3')}}</p>
-            <a style="margin-top:10px;color:turquoise;display:inline-block;" href="https://teammodelstorage.blob.core.chinacloudapi.cn/teammodelcontest/20191107/%E5%AD%A6%E7%94%9F%E8%B4%A6%E5%8F%B7%E5%90%8D%E5%8D%95%20%E2%80%94%E6%AD%A3%E7%A1%AE%E6%95%B0%E6%8D%AE.xlsx">(下载名单模板)</a>
+            <a style="margin-top:10px;color:turquoise;display:inline-block;" href="https://teammodelstorage.blob.core.chinacloudapi.cn/download/%E5%AD%A6%E7%94%9F%E5%90%8D%E5%8D%95%E6%A8%A1%E6%9D%BF.xlsx">(下载名单模板)</a>
         </div>
         <div class="form-body" style="background:none;" v-else>
             <div class="ivu-upload-list-file">

+ 26 - 0
TEAMModelOS/ClientApp/src/view/student-account/Index.less

@@ -116,4 +116,30 @@
     line-height: 33px;
     font-size: 18px;
     font-weight: 600;
+}
+.stu-mgt-header{
+    height: 50px;
+    border-bottom: 1px solid #353535;
+    padding: 0 20px;
+    .tab-box {
+        display: inline-block;
+        width: 30%;
+        min-width: 303px;
+        .pane{
+            font-weight: bold;
+            margin-right: 50px;
+            color: #777777;
+            line-height: 50px;
+            padding: 5px 0;
+            cursor: pointer;
+            vertical-align: middle;
+            &.active{
+                color: #e2e2e2;
+                border-bottom: 1px #777777 solid;
+            }
+        }
+    }
+}
+.class-mgt-wrap{
+    height: ~"calc(100% - 50px)";
 }

+ 238 - 177
TEAMModelOS/ClientApp/src/view/student-account/Index.vue

@@ -1,105 +1,118 @@
 <style lang="less" scoped>
-@import './Index.less';
+@import "./Index.less";
 </style>
 <style lang="less">
-@import './IndexIview.less';
+@import "./IndexIview.less";
 </style>
 
 <template>
     <div class="sc-container">
         <Loading v-if="isloading == true"></Loading>
-        <!--菜单栏-->
-        <div class="sc-menu">
-            <div class="sc-menu-left dark-iview-select">
-                <!-- 學制Select -->
-                <Select v-model="searchPeriod" style="width: 120px" :placeholder="$t('stuAccount.periodHolder')" @on-change="filterData">
-                    <Option v-for="(item, index) in periods" :value="item.id" :key="index">{{ item.name }}</Option>
-                </Select>
-                <!-- 學級Select -->
-                <Select v-model="searchGrade" style="width: 120px; margin-left: 5px" :placeholder="$t('stuAccount.gradeHolder')" :not-found-text="$t('stuAccount.sltPdFirst')" clearable @on-change="filterData">
-                    <Option v-for="(item, index) in filterGrades" :value="item.id" :key="index">{{ item.name }}</Option>
-                </Select>
-                <!-- 教室Select -->
-                <Select v-model="searchClassroom" ref="classroom" style="width: 150px; margin-left: 5px" :placeholder="$t('stuAccount.classroomHolder')" clearable @on-change="filterData" :not-found-text="searchGrade ? $t('stuAccount.noClass') : $t('stuAccount.sltGdFirst')">
-                    <Option v-for="(item, index) in filterClasses" :value="item.id" :key="index">{{ item.name }}</Option>
-                    <Option value="noclass">{{$t('stuAccount.noRelClass')}}</Option>
-                </Select>
-                <!-- 字串模糊搜尋 -->
-                <Input v-model="searchText" clearable :placeholder="$t('stuAccount.searchHolder')" style="width: 220px; margin-left: 20px" search @on-search="filterData" @on-clear="filterData" />
-            </div>
-            <div class="sc-menu-right sc-text-no-select" v-if="authorizationStatus == false">
-                <ul v-if="$access.can('admin.*|student-upd')">
-                    <!--授權管理開關-->
-                    <li @click="showAuthorization()">
-                        <Icon custom="iconfont icon-auth-key" color="white" size="18" />
-                        <span>{{ $t('stuAccount.menuAuth') }}</span>
-                    </li>
-                    <!--授權管理開關-->
-                    <li @click="importStudent()">
-                        <Icon type="md-arrow-round-up" color="white" size="18" />
-                        <span>{{ $t('stuAccount.importStu') }}</span>
-                    </li>
-                    <li @click="addStudent()">
-                        <Icon type="md-add" color="white" size="18" />
-                        <span>{{ $t('stuAccount.addStu') }}</span>
-                    </li>
-                    <li @click="delStudent(-1)" :class="selections.length > 0 ? '' : 'sc-disable-cursor'">
-                        <Icon type="md-trash" :color="selections.length > 0 ? 'white' : '#606060'" size="18" />
-                        <span>{{ $t('stuAccount.delStu') }}</span>
-                    </li>
-                    <li @click="editStudent()" :class="selections.length > 0 ? '' : 'sc-disable-cursor'">
-                        <Icon type="md-create" :color="selections.length > 0 ? 'white' : '#606060'" size="18" />
-                        <span>{{ $t('stuAccount.editInfo') }}</span>
-                    </li>
-                    <li @click="resetPW(-1)" :class="selections.length > 0 ? '' : 'sc-disable-cursor'">
-                        <Icon custom="iconfont icon-reset" :color="selections.length > 0 ? 'white' : '#606060'" size="18" />
-                        <span>{{$t('stuAccount.resetPw')}}</span>
-                    </li>
-                </ul>
+        <!-- tab切换 -->
+        <div class="stu-mgt-header">
+            <div class="tab-box">
+                <span class="pane" @click="tab = 'list'" :class="{ active: tab === 'list' }">
+                    学生管理
+                </span>
+                <span class="pane" @click="tab = 'class'" :class="{ active: tab === 'class' }">
+                    班级管理
+                </span>
             </div>
         </div>
-        <!--学生账号table-->
-        <div class="sc-content dark-iview-table"
-             style="position: relative; padding-left: 20px"
-             :style="{width: authorizationStatus == true ? '70%' : '100%',transition: 'all 0.7s'}">
-            <Scroll :on-reach-bottom="scrollLoad" height="750" :distance-to-edge="[15, 15]">
-                <Table ref="selection" :columns="tableColumns" :data="tableShowData" :loading="tableLoading" @on-selection-change="getSelectInfo">
-                    <template slot-scope="{ row }" slot="status">
-                        <Icon custom="iconfont icon-auth-key"
-                              size="25"
-                              :style="{
+        <!-- 账号管理 -->
+        <div v-show="tab == 'list'">
+            <!--菜单栏-->
+            <div class="sc-menu">
+                <div class="sc-menu-left dark-iview-select">
+                    <!-- 學制Select -->
+                    <Select v-model="searchPeriod" style="width: 120px" :placeholder="$t('stuAccount.periodHolder')" @on-change="filterData">
+                        <Option v-for="(item, index) in periods" :value="item.id" :key="index">{{ item.name }}</Option>
+                    </Select>
+                    <!-- 學級Select -->
+                    <Select v-model="searchGrade" style="width: 120px; margin-left: 5px" :placeholder="$t('stuAccount.gradeHolder')" :not-found-text="$t('stuAccount.sltPdFirst')" clearable @on-change="filterData">
+                        <Option v-for="(item, index) in years" :value="item.value" :key="index">{{ item.label }}</Option>
+                    </Select>
+                    <!-- 教室Select -->
+                    <Select v-model="searchClassroom" ref="classroom" style="width: 150px; margin-left: 5px" :placeholder="$t('stuAccount.classroomHolder')" clearable @on-change="filterData" :not-found-text="searchGrade ? $t('stuAccount.noClass') : $t('stuAccount.sltGdFirst')">
+                        <Option v-for="(item, index) in filterClasses" :value="item.id" :key="index">{{ item.name }}</Option>
+                        <Option value="noclass">{{$t('stuAccount.noRelClass')}}</Option>
+                    </Select>
+                    <!-- 字串模糊搜尋 -->
+                    <Input v-model="searchText" clearable :placeholder="$t('stuAccount.searchHolder')" style="width: 220px; margin-left: 20px" search @on-search="filterData" @on-clear="filterData" />
+                </div>
+                <div class="sc-menu-right sc-text-no-select" v-if="authorizationStatus == false">
+                    <ul v-if="$access.can('admin.*|student-upd')">
+                        <!--授權管理開關-->
+                        <li @click="showAuthorization()">
+                            <Icon custom="iconfont icon-auth-key" color="white" size="18" />
+                            <span>{{ $t('stuAccount.menuAuth') }}</span>
+                        </li>
+                        <!--授權管理開關-->
+                        <li @click="importStudent()">
+                            <Icon type="md-arrow-round-up" color="white" size="18" />
+                            <span>{{ $t('stuAccount.importStu') }}</span>
+                        </li>
+                        <li @click="addStudent()">
+                            <Icon type="md-add" color="white" size="18" />
+                            <span>{{ $t('stuAccount.addStu') }}</span>
+                        </li>
+                        <li @click="delStudent(-1)" :class="selections.length > 0 ? '' : 'sc-disable-cursor'">
+                            <Icon type="md-trash" :color="selections.length > 0 ? 'white' : '#606060'" size="18" />
+                            <span>{{ $t('stuAccount.delStu') }}</span>
+                        </li>
+                        <li @click="editStudent()" :class="selections.length > 0 ? '' : 'sc-disable-cursor'">
+                            <Icon type="md-create" :color="selections.length > 0 ? 'white' : '#606060'" size="18" />
+                            <span>{{ $t('stuAccount.editInfo') }}</span>
+                        </li>
+                        <li @click="resetPW(-1)" :class="selections.length > 0 ? '' : 'sc-disable-cursor'">
+                            <Icon custom="iconfont icon-reset" :color="selections.length > 0 ? 'white' : '#606060'" size="18" />
+                            <span>{{$t('stuAccount.resetPw')}}</span>
+                        </li>
+                    </ul>
+                </div>
+            </div>
+            <!--学生账号table-->
+            <div class="sc-content dark-iview-table" style="position: relative; padding-left: 20px" :style="{width: authorizationStatus == true ? '70%' : '100%',transition: 'all 0.7s'}">
+                <Scroll :on-reach-bottom="scrollLoad" height="750" :distance-to-edge="[15, 15]">
+                    <Table ref="selection" :columns="tableColumns" :data="tableShowData" :loading="tableLoading" @on-selection-change="getSelectInfo">
+                        <template slot-scope="{ row }" slot="status">
+                            <Icon custom="iconfont icon-auth-key" size="25" :style="{
                 color: aclassOneInfoNum != undefined && (aclassOneInfoNum.staIds.includes(row.id) == true || aclassOneInfoNum.dyncIds.includes(row.id)) == true ? '#00f492' : '#565656'
               }" />
-                    </template>
-                    <template slot-scope="{ row, index }" slot="header">
-                        <!--<span class="name-header" :style="{background:bgColor[index % 12]}">{{getFirstChart(row.name)}}</span>-->
-                        <PersonalPhoto :name="row.name" :picture="row.picture" :color="bgColor[index % 12]" />
-                    </template>
-                    <template slot-scope="{ row }" slot="gradeId" v-if="authorizationStatus == false">
-                        <span>{{ getGradeName(row.gradeId) }}</span>
-                    </template>
-                    <template slot-scope="{ row }" slot="classId">
-                        <span>{{ row.className }}</span>
-                    </template>
-                    <template slot-scope="{ row }" slot="no">
-                        <span>{{ row.no }}</span>
-                    </template>
-                    <template slot-scope="{ row }" slot="gradeName">
-                        <span>{{ row.gradeName }}</span>
-                    </template>
-                    <template slot-scope="{ row }" slot="action" v-if="authorizationStatus == false">
-                        <div class="item-tools" v-if="$access.can('admin.*|student-upd')">
-                            <Icon type="md-create" size="18" color="white" @click="editStudent(row)" title="修改" />
-                            <Icon custom="iconfont icon-reset" size="18" color="white" @click="resetPW(row)" :title=" $t('stuAccount.resetPw')" />
-                            <Icon type="md-trash" size="18" color="white" @click="delStudent(row)" :title="$t('stuAccount.delStu')" />
-                        </div>
-                    </template>
-                </Table>
-            </Scroll>
+                        </template>
+                        <template slot-scope="{ row, index }" slot="header">
+                            <!--<span class="name-header" :style="{background:bgColor[index % 12]}">{{getFirstChart(row.name)}}</span>-->
+                            <PersonalPhoto :name="row.name" :picture="row.picture" :color="bgColor[index % 12]" />
+                        </template>
+                        <template slot-scope="{ row }" slot="gradeId" v-if="authorizationStatus == false">
+                            <span>{{ getGradeName(row.gradeId) }}</span>
+                        </template>
+                        <template slot-scope="{ row }" slot="classId">
+                            <span>{{ row.className }}</span>
+                        </template>
+                        <template slot-scope="{ row }" slot="no">
+                            <span>{{ row.no }}</span>
+                        </template>
+                        <template slot-scope="{ row }" slot="gradeName">
+                            <span>{{ row.gradeName }}</span>
+                        </template>
+                        <template slot-scope="{ row }" slot="action" v-if="authorizationStatus == false">
+                            <div class="item-tools" v-if="$access.can('admin.*|student-upd')">
+                                <Icon type="md-create" size="18" color="white" @click="editStudent(row)" title="修改" />
+                                <Icon custom="iconfont icon-reset" size="18" color="white" @click="resetPW(row)" :title=" $t('stuAccount.resetPw')" />
+                                <Icon type="md-trash" size="18" color="white" @click="delStudent(row)" :title="$t('stuAccount.delStu')" />
+                            </div>
+                        </template>
+                    </Table>
+                </Scroll>
 
-            <AclassOneAuth :students="students" :selected="selections" @closeAuth="closeAuth" :closefromBtn="closefromBtn" />
+                <AclassOneAuth :students="students" :selected="selections" @closeAuth="closeAuth" :closefromBtn="closefromBtn" />
+            </div>
+        </div>
+        <!-- 班级管理 -->
+        <div v-show="tab == 'class'" class="class-mgt-wrap" id="class-mgt-list">
+            <ClassMgt></ClassMgt>
         </div>
-
         <Modal v-model="addStudentStatus" width="520" class-name="add-student dark-iview-modal" :mask-closable="false">
             <add-student v-if="addStudentStatus" :schoolCode="$store.state.user.schoolCode" :isShow="addStudentStatus" :editStudentInfo="editStudentInfo" @saveStudentInfo="closeAddStudent" :bizType="bizType"></add-student>
             <div slot="footer"></div>
@@ -127,11 +140,11 @@
 <script>
 import PersonalPhoto from '@/components/public/personalPhoto/Index.vue'
 import AddStudent from './AddStudent'
+import ClassMgt from './ClassMgt'
 import ImportStudent from './ImportStudent'
 import Authorization from './Authorization'
 import AclassOneAuth from './AclassOneAuth'
 import { mapGetters, mapMutations } from 'vuex'
-import Loading from '@/common/Loading.vue'
 export default {
     components: {
         AddStudent,
@@ -139,10 +152,11 @@ export default {
         Authorization,
         PersonalPhoto,
         AclassOneAuth,
-        Loading
+        ClassMgt
     },
     data() {
         return {
+            tab: 'list',
             totalNum: 0,
             bgColor: ['#4ECDC4', '#F99406', '#075CD0', '#F7CA17', '#F2774B', '#67809F', '#BF55ED', '#00B169', '#F72459', '#F15A22', '#03C9A8', '#9A1294'],
             classroomList: [],
@@ -151,7 +165,9 @@ export default {
             searchPeriod: '',
             searchGrade: '',
             searchClassroom: '',
-            schoolData: {},
+            schoolBase:{
+                period:[]
+            },
             tableLoading: true,
             searchText: '',
             currentPage: 1,
@@ -184,11 +200,11 @@ export default {
             if (row != -1) {
                 this.$Modal.confirm({
                     title: this.$t('cusMgt.resetPw'),
-                    content: '<p>' + this.$t('cusMgt.resetPwContent1') + " <strong style='color:red;'>" + row.name + '</strong>'+ this.$t('cusMgt.resetPwContent1') +'?</p>',
+                    content: '<p>' + this.$t('cusMgt.resetPwContent1') + " <strong style='color:red;'>" + row.name + '</strong>' + this.$t('cusMgt.resetPwContent1') + '?</p>',
                     onOk: () => {
                         let ids = []
                         row.pw = row.id
-                        row.year = row.year ? row.year.toString() :''
+                        row.year = row.year ? row.year.toString() : ''
                         delete row.no
                         ids.push(row)
                         this.tableLoading = true
@@ -209,10 +225,10 @@ export default {
                 if (this.selections.length > 0) {
                     this.$Modal.confirm({
                         title: this.$t('cusMgt.resetPw'),
-                        content: '<p>' + this.$t('cusMgt.resetPwContent3') + " <strong style='color:red;'>" + this.selections.length + '</strong>'+ this.$t('cusMgt.resetPwContent4') +'</p>',
+                        content: '<p>' + this.$t('cusMgt.resetPwContent3') + " <strong style='color:red;'>" + this.selections.length + '</strong>' + this.$t('cusMgt.resetPwContent4') + '</p>',
                         onOk: () => {
                             this.tableLoading = true
-                            let apiData = this.selections.map( (item) =>{
+                            let apiData = this.selections.map((item) => {
                                 let d = item
                                 d.pw = d.id
                                 delete d.no
@@ -290,7 +306,7 @@ export default {
                 data.studentInfos.year = parseInt(data.studentInfos.year)
                 newStudents.push(data.studentInfos)
             } else if (data.action == 2) {  // 修改
-                newStudents = data.studentInfos.map(function(item) {
+                newStudents = data.studentInfos.map(function (item) {
                     let temp = item
                     temp.pw = '******'
                     temp.year = parseInt(temp.year)
@@ -304,7 +320,7 @@ export default {
         },
         closeImportStudent(data) {
             // 給一個 PW 讓AddStudent.vue 的Watch 可以動作
-            let newStudents = data.map(function(item) {
+            let newStudents = data.map(function (item) {
                 let temp = item
                 temp.pw = '******'
                 temp.year = parseInt(temp.year)
@@ -324,7 +340,7 @@ export default {
                 this.isloading = false
             }, 1000)
         },
-   
+
         addStudent() {
             this.bizType = 1
             this.$refs.selection.clearCurrentRow()
@@ -340,63 +356,63 @@ export default {
             this.isloading = true
             setTimeout(() => {
                 this.tableColumns = [
-                {
-                    type: 'selection',
-                    width: 80,
-                    align: 'center'
-                },
-                {
-                    slot: 'header',
-                    title: ' ',
-                    align: 'center',
-                    width: 120
-                },
-                {
-                    key: 'id',
-                    title: this.$t('stuAccount.account'),
-                    align: 'center',
-                    sortable: true,
-                    sortMethod: (a, b, type) => {
-                        if (type == 'asc') {
-                            return a.localeCompare(b)
-                        } else {
-                            return b.localeCompare(a)
+                    {
+                        type: 'selection',
+                        width: 80,
+                        align: 'center'
+                    },
+                    {
+                        slot: 'header',
+                        title: ' ',
+                        align: 'center',
+                        width: 120
+                    },
+                    {
+                        key: 'id',
+                        title: this.$t('stuAccount.account'),
+                        align: 'center',
+                        sortable: true,
+                        sortMethod: (a, b, type) => {
+                            if (type == 'asc') {
+                                return a.localeCompare(b)
+                            } else {
+                                return b.localeCompare(a)
+                            }
                         }
-                    }
-                },
-                {
-                    key: 'name',
-                    title: this.$t('stuAccount.stuName'),
-                    align: 'center',
-                    sortable: true
-                },
-                {
-                    slot: 'classId',
-                    title: this.$t('stuAccount.classroomName'),
-                    align: 'center',
-                    sortable: true
-                },
-                {
-                    key: 'no',
-                    title: this.$t('stuAccount.seatNo'),
-                    align: 'center',
-                    width: 120,
-                    sortable: true,
-                    sortMethod: (a, b, type) => {
-                        if (type == 'desc') {
-                            return parseInt(a) > parseInt(b) ? -1 : 1
-                        } else {
-                            return parseInt(a) < parseInt(b) ? -1 : 1
+                    },
+                    {
+                        key: 'name',
+                        title: this.$t('stuAccount.stuName'),
+                        align: 'center',
+                        sortable: true
+                    },
+                    {
+                        slot: 'classId',
+                        title: this.$t('stuAccount.classroomName'),
+                        align: 'center',
+                        sortable: true
+                    },
+                    {
+                        key: 'no',
+                        title: this.$t('stuAccount.seatNo'),
+                        align: 'center',
+                        width: 120,
+                        sortable: true,
+                        sortMethod: (a, b, type) => {
+                            if (type == 'desc') {
+                                return parseInt(a) > parseInt(b) ? -1 : 1
+                            } else {
+                                return parseInt(a) < parseInt(b) ? -1 : 1
+                            }
                         }
+                    },
+                    {
+                        slot: 'status',
+                        title: this.$t('stuAccount.authStatus'),
+                        align: 'center',
+                        width: 150,
+                        sortable: true
                     }
-                },
-                {
-                    slot: 'status',
-                    title: this.$t('stuAccount.authStatus'),
-                    align: 'center',
-                    width: 150,
-                    sortable: true
-                }
                 ]
                 this.isloading = false
             }, 1000)
@@ -459,7 +475,7 @@ export default {
                 if (this.selections.length > 0) {
                     this.$Modal.confirm({
                         title: this.$t('stuAccount.tips2Title'),
-                        content: '<p>' + this.$t('stuAccount.tips2Content3') + " <strong style='color:red;'>" + this.selections.length + '</strong>'+ this.$t('stuAccount.tips2Content4') +'</p>',
+                        content: '<p>' + this.$t('stuAccount.tips2Content3') + " <strong style='color:red;'>" + this.selections.length + '</strong>' + this.$t('stuAccount.tips2Content4') + '</p>',
                         onOk: () => {
                             this.tableLoading = true
                             let delIds = this.selections.map(item => {
@@ -517,15 +533,34 @@ export default {
                     sortable: true
                 },
                 {
-                    slot: 'gradeId',
-                    title: this.$t('stuAccount.grade'),
+                    key: 'stuId',
+                    title: '学号',
+                    align: 'center',
+                    sortable: true
+                },
+                // {
+                //     slot: 'gradeId',
+                //     title: this.$t('stuAccount.grade'),
+                //     align: 'center',
+                //     width: 140,
+                //     sortable: true
+                // },
+                {
+                    key: 'year',
+                    title: '学级',
                     align: 'center',
                     width: 140,
                     sortable: true
                 },
+                // {
+                //     slot: 'classId',
+                //     title: this.$t('stuAccount.classroomName'),
+                //     align: 'center',
+                //     sortable: true
+                // },
                 {
                     slot: 'classId',
-                    title: this.$t('stuAccount.classroomName'),
+                    title: '班级',
                     align: 'center',
                     sortable: true
                 },
@@ -547,7 +582,7 @@ export default {
                     slot: 'status',
                     title: this.$t('stuAccount.authStatus'),
                     align: 'center',
-                    width: 100,
+                    width: 120,
                     sortable: true
                 },
                 {
@@ -564,7 +599,7 @@ export default {
                 res => {
                     this.tableLoading = false
                     // 給一個 PW 讓AddStudent.vue 的Watch 可以動作
-                    let newStudents = res.students.map(function(item) {
+                    let newStudents = res.students.map(function (item) {
                         let temp = item
                         temp.pw = '******'
                         return temp
@@ -587,9 +622,9 @@ export default {
             )
         },
         /** 取得年級Name */
-        getGradeName: function(gradeId) {
+        getGradeName: function (gradeId) {
             if (gradeId != null) {
-                let gradeData = this.grades.filter(function(item) {
+                let gradeData = this.grades.filter(function (item) {
                     return item.id == gradeId
                 })
                 return gradeData[0].name
@@ -610,7 +645,7 @@ export default {
             )
         },
 
-        scrollLoad: function() {
+        scrollLoad: function () {
             setTimeout(() => {
                 let maxLength = this.tableShowData.length
                 let temp = this.tableFilterData.slice(this.pointNum + 1, this.pointNum + this.basicCount)
@@ -625,14 +660,14 @@ export default {
             }, 1500)
         },
         /**根据学段、年级、班级搜索 */
-        filterData: function() {
+        filterData: function () {
             let data = this.students
 
             // 筛选没有关联班级的学生
             if (this.searchClassroom == 'noclass') {
                 if (this.searchClassroom) {
                     let id = this.searchClassroom
-                    data = data.filter(function(item) {
+                    data = data.filter(function (item) {
                         return item.classId == null
                     })
                 }
@@ -646,7 +681,7 @@ export default {
             // 帳號資訊搜尋
             if (this.searchText) {
                 let text = this.searchText
-                data = data.filter(function(item) {
+                data = data.filter(function (item) {
                     return item.name.indexOf(text) >= 0 || item.id.indexOf(text) >= 0
                 })
             }
@@ -654,23 +689,23 @@ export default {
             // 學制篩選
             if (this.searchPeriod) {
                 let id = this.searchPeriod
-                data = data.filter(function(item) {
-                return item.periodId == id
+                data = data.filter(function (item) {
+                    return item.periodId == id
                 })
             }
 
             // 年級篩選
             if (this.searchGrade) {
                 let id = this.searchGrade
-                data = data.filter(function(item) {
-                    return item.gradeId == id
+                data = data.filter(function (item) {
+                    return item.year == id
                 })
             }
 
             // 教室篩選
             if (this.searchClassroom) {
                 let id = this.searchClassroom
-                data = data.filter(function(item) {
+                data = data.filter(function (item) {
                     return item.classId == id
                 })
             }
@@ -684,6 +719,11 @@ export default {
         })
     },
     created() {
+        this.$store.dispatch('user/getSchoolProfile').then(
+            res => {
+                this.schoolBase = res.school_base
+            }
+        )
         this.initData()
         this.baseFindStudent()
     },
@@ -695,11 +735,11 @@ export default {
             students: 'schoolBaseInfo/getStudent', // 學生List
             aclassOneInfoNum: 'studentAclassOneAuth/getSchoolAclassOneInfoNum'
         }),
-        filterGrades: function() {
+        filterGrades: function () {
             var data = this.grades
             if (this.searchPeriod) {
                 let periodId = this.searchPeriod
-                data = data.filter(function(item) {
+                data = data.filter(function (item) {
                     return item.periodId == periodId
                 })
                 return data
@@ -707,11 +747,11 @@ export default {
                 return []
             }
         },
-        filterClasses: function() {
+        filterClasses: function () {
             var data = this.classes
             if (this.searchGrade) {
                 let gradeId = this.searchGrade
-                data = data.filter(function(item) {
+                data = data.filter(function (item) {
                     return item.gradeId == gradeId
                 })
                 return data
@@ -719,20 +759,41 @@ export default {
                 return []
             }
         },
-        getPeriodName: function() {
+        getPeriodName: function () {
             let str = ''
-            if(this.periods){
+            if (this.periods) {
                 let id = this.searchPeriod
                 let period = this.periods.filter((item) => {
                     return item.id == id
                 })
-                if(period[0]) str = period[0].name
+                if (period[0]) str = period[0].name
             }
             return str
+        },
+        years(){
+            if(this.schoolBase && this.schoolBase.period.length && this.searchPeriod){
+                let pData = this.schoolBase.period.find(item=>{
+                    return item.id == this.searchPeriod
+                })
+                if(pData){
+                    let year = (new Date()).getFullYear()
+                    console.log(pData)
+                    let res = pData.grades.map(item=>{
+                        return {
+                            label:`${item.name}(${year}级)`,
+                            value:year--
+                        }
+                    })
+                    return res
+                }else{
+                    return []
+                }
+            }
+            return []
         }
     },
     watch: {
-        selections: function(value) {
+        selections: function (value) {
             console.log(value)
         }
     },