Ver código fonte

完成学生账号管理、更新iview到4.0

liqk 5 anos atrás
pai
commit
d4208594b9
26 arquivos alterados com 2292 adições e 205 exclusões
  1. 6 1
      TEAMModelOS.Model/BaseInfo/Models/ClassRoom.cs
  2. 12 0
      TEAMModelOS.Model/BaseInfo/Models/Point.cs
  3. 3 2
      TEAMModelOS.Model/BaseInfo/Models/SSystem.cs
  4. 2 2
      TEAMModelOS.Model/BaseInfo/Models/SchoolSystem.cs
  5. 1 1
      TEAMModelOS.Service/Core/Implements/ClassRoomService.cs
  6. 4 1
      TEAMModelOS/ClientApp/api/schoolSetting.js
  7. 5 3
      TEAMModelOS/ClientApp/app.js
  8. 1 1
      TEAMModelOS/ClientApp/filters/http.js
  9. 3 3
      TEAMModelOS/ClientApp/locale/index.js
  10. 5 1
      TEAMModelOS/ClientApp/router/routes.js
  11. 113 0
      TEAMModelOS/ClientApp/utils/excel.js
  12. 51 30
      TEAMModelOS/ClientApp/view/school-mgmt/ClassroomSetting/ClassroomSetting.less
  13. 66 62
      TEAMModelOS/ClientApp/view/school-mgmt/ClassroomSetting/ClassroomSetting.vue
  14. 92 97
      TEAMModelOS/ClientApp/view/school-mgmt/SystemSetting/SystemSetting.vue
  15. 82 0
      TEAMModelOS/ClientApp/view/student-account/Index.less
  16. 282 0
      TEAMModelOS/ClientApp/view/student-account/Index.vue
  17. 101 0
      TEAMModelOS/ClientApp/view/student-account/IndexIview.less
  18. 26 0
      TEAMModelOS/ClientApp/view/student-account/add-student/AddStudent.less
  19. 332 0
      TEAMModelOS/ClientApp/view/student-account/add-student/AddStudent.vue
  20. 147 0
      TEAMModelOS/ClientApp/view/student-account/add-student/Authorization.less
  21. 263 0
      TEAMModelOS/ClientApp/view/student-account/add-student/Authorization.vue
  22. 137 0
      TEAMModelOS/ClientApp/view/student-account/add-student/IImportStudent.less
  23. 123 0
      TEAMModelOS/ClientApp/view/student-account/add-student/ImportExcel.vue
  24. 95 0
      TEAMModelOS/ClientApp/view/student-account/add-student/ImportStudent.less
  25. 339 0
      TEAMModelOS/ClientApp/view/student-account/add-student/ImportStudent.vue
  26. 1 1
      TEAMModelOS/package.json

+ 6 - 1
TEAMModelOS.Model/BaseInfo/Models/ClassRoom.cs

@@ -8,10 +8,15 @@ namespace TEAMModelOS.Model.BaseInfo.Models
 {
     public class Classroom
     {
+        public Classroom() {
+            point = new Point();
+        }
         [JsonProperty(PropertyName = "id")]
         public string Id { get; set; }
         [PartitionKey]
-        public string Code { get; set; }
+        public string SchoolCode { get; set; }
+        public string ClassroomCode { get; set; }
+        public Point point { get; set; }
         public string Name { get; set; }
         public string HeadMaster { get; set; }
         public string Period { get; set; }

+ 12 - 0
TEAMModelOS.Model/BaseInfo/Models/Point.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.Model.BaseInfo.Models
+{
+    public class Point
+    {
+        public float X { get; set; }
+        public float Y { get; set; }
+    }
+}

+ 3 - 2
TEAMModelOS.Model/BaseInfo/Models/SSystem.cs

@@ -4,9 +4,9 @@ using System.Text;
 
 namespace TEAMModelOS.Model.BaseInfo.Models
 {
-    public class SSystem
+    public class Period
     {
-        public SSystem() {
+        public Period() {
             Grade = new List<Grades>();
             Subject = new List<Subjects>();
             Semester = new List<Semester>();
@@ -15,6 +15,7 @@ namespace TEAMModelOS.Model.BaseInfo.Models
         public List<Subjects> Subject { get; set; }
         public List<Semester> Semester { get; set; }
         public string Name { get; set; }
+        public string Code { get; set; }
         public int GradeCount { get; set; }
         public int SemesterCount { get; set; }
         public int SubjectCount { get; set; }

+ 2 - 2
TEAMModelOS.Model/BaseInfo/Models/SchoolSystem.cs

@@ -9,7 +9,7 @@ namespace TEAMModelOS.Model.BaseInfo.Models
     public class SchoolSystem
     {
         public SchoolSystem() {
-            Systems = new List<SSystem>();
+            Period = new List<Period>();
             //Semesters = new List<Semester>();
 
         }
@@ -18,7 +18,7 @@ namespace TEAMModelOS.Model.BaseInfo.Models
         [PartitionKey]
         public string Code { get; set; }
         public string Name { get; set; }
-        public List<SSystem> Systems { get; set; }
+        public List<Period> Period { get; set; }
        
     }
 }

+ 1 - 1
TEAMModelOS.Service/Core/Implements/ClassRoomService.cs

@@ -24,7 +24,7 @@ namespace TEAMModelOS.Service.Core.Implements
 
         public async Task<Classroom> UpdateRoom(Classroom classRoom)
         {
-            await _cosmosrepository.ReplaceObject(classRoom, classRoom.Id, classRoom.HiTeach);
+            await _cosmosrepository.ReplaceObject(classRoom, classRoom.Id, classRoom.SchoolCode);
             return classRoom;
             //throw new NotImplementedException();
         }

+ 4 - 1
TEAMModelOS/ClientApp/api/schoolSetting.js

@@ -8,5 +8,8 @@ export default {
   },
   findSchoolSystem: function (data) {
     return post('/api/SchoolSystem/FindSchoolSystem', data);
-  }
+  },
+  findClassInfo: function (data) {
+    return post('/api/Classroom/FindClassInfo', data);
+  },
 }

+ 5 - 3
TEAMModelOS/ClientApp/app.js

@@ -6,8 +6,10 @@ import store from './store'
 import { sync } from 'vuex-router-sync'
 import App from 'components/app-root'
 import { FontAwesomeIcon } from './icons'
-import iView from 'iview';
-import 'iview/dist/styles/iview.css';
+//import iView from 'iview';
+//import 'iview/dist/styles/iview.css';
+import ViewUI from 'view-design';
+import 'view-design/dist/styles/iview.css';
 import commons from "@/utils/public.js";
 import apiTools from '@/api';
 import mockTools from '@/mock';
@@ -115,7 +117,7 @@ router.afterEach((to, from, next) => {
 
 
 
-Vue.use(iView, {
+Vue.use(ViewUI, {
   i18n: (key, value) => i18n.t(key, value)
 })
 

+ 1 - 1
TEAMModelOS/ClientApp/filters/http.js

@@ -1,5 +1,5 @@
 import axios from 'axios';
-import { Message } from 'iview';
+import { Message } from 'view-design';
 import router from '@/router/index'
 axios.defaults.timeout = 10000; //设置超时时长
 axios.defaults.baseURL ='';

+ 3 - 3
TEAMModelOS/ClientApp/locale/index.js

@@ -4,9 +4,9 @@ import customZhCn from './lang/zh-CN'
 import customZhTw from './lang/zh-TW'
 import customEnUs from './lang/en-US'
 
-import zhLocale from "iview/src/locale/lang/zh-CN";
-import enLocale from "iview/src/locale/lang/en-US";
-import twLocale from "iview/src/locale/lang/zh-TW";
+import zhLocale from "view-design/src/locale/lang/zh-CN";
+import enLocale from "view-design/src/locale/lang/en-US";
+import twLocale from "view-design/src/locale/lang/zh-TW";
 
 Vue.use(VueI18n)
 

+ 5 - 1
TEAMModelOS/ClientApp/router/routes.js

@@ -118,7 +118,11 @@ export const routes = [
       }
     ]
   },
-
+  //学生账号管理
+  {
+    path: '/studentAccount',
+    component: resolve => require(['@/view/student-account/index.vue'], resolve),
+  },
 
   //课纲管理
   {

+ 113 - 0
TEAMModelOS/ClientApp/utils/excel.js

@@ -0,0 +1,113 @@
+/* eslint-disable */
+import XLSX from 'xlsx';
+
+function auto_width(ws, data) {
+    /*set worksheet max width per col*/
+    const colWidth = data.map(row => row.map(val => {
+        /*if null/undefined*/
+        if (val == null) {
+            return { 'wch': 10 };
+        }
+        /*if chinese*/
+        else if (val.toString().charCodeAt(0) > 255) {
+            return { 'wch': val.toString().length * 2 };
+        } else {
+            return { 'wch': val.toString().length };
+        }
+    }))
+    /*start in the first row*/
+    let result = colWidth[0];
+    for (let i = 1; i < colWidth.length; i++) {
+        for (let j = 0; j < colWidth[i].length; j++) {
+            if (result[j]['wch'] < colWidth[i][j]['wch']) {
+                result[j]['wch'] = colWidth[i][j]['wch'];
+            }
+        }
+    }
+    ws['!cols'] = result;
+}
+
+function json_to_array(key, jsonData) {
+    return jsonData.map(v => key.map(j => { return v[j] }));
+}
+
+// fix data,return string
+function fixdata(data) {
+    let o = ''
+    let l = 0
+    const w = 10240
+    for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
+    o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
+    return o
+}
+
+// get head from excel file,return array
+function get_header_row(sheet) {
+    const headers = []
+    const range = XLSX.utils.decode_range(sheet['!ref'])
+    let C
+    const R = range.s.r /* start in the first row */
+    for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
+        var cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] /* find the cell in the first row */
+        var hdr = 'UNKNOWN ' + C // <-- replace with your desired default
+        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
+        headers.push(hdr)
+    }
+    return headers
+}
+
+export const export_table_to_excel = (id, filename) => {
+    const table = document.getElementById(id);
+    const wb = XLSX.utils.table_to_book(table);
+    XLSX.writeFile(wb, filename);
+
+    /* the second way */
+    // const table = document.getElementById(id);
+    // const wb = XLSX.utils.book_new();
+    // const ws = XLSX.utils.table_to_sheet(table);
+    // XLSX.utils.book_append_sheet(wb, ws, filename);
+    // XLSX.writeFile(wb, filename);
+}
+
+export const export_json_to_excel = ({ data, key, title, filename, autoWidth }) => {
+    const wb = XLSX.utils.book_new();
+    data.unshift(title);
+    const ws = XLSX.utils.json_to_sheet(data, { header: key, skipHeader: true });
+    if (autoWidth) {
+        const arr = json_to_array(key, data);
+        auto_width(ws, arr);
+    }
+    XLSX.utils.book_append_sheet(wb, ws, filename);
+    XLSX.writeFile(wb, filename + '.xlsx');
+}
+
+export const export_array_to_excel = ({ key, data, title, filename, autoWidth }) => {
+    const wb = XLSX.utils.book_new();
+    const arr = json_to_array(key, data);
+    arr.unshift(title);
+    const ws = XLSX.utils.aoa_to_sheet(arr);
+    if (autoWidth) {
+        auto_width(ws, arr);
+    }
+    XLSX.utils.book_append_sheet(wb, ws, filename);
+    XLSX.writeFile(wb, filename + '.xlsx');
+}
+
+export const read = (data, type) => {
+  /* if type == 'base64' must fix data first */
+  // const fixedData = fixdata(data)
+  // const workbook = XLSX.read(btoa(fixedData), { type: 'base64' })
+  const workbook = XLSX.read(data, { type: type });
+  const firstSheetName = workbook.SheetNames[0];
+  const worksheet = workbook.Sheets[firstSheetName];
+  const header = get_header_row(worksheet);
+  const results = XLSX.utils.sheet_to_json(worksheet);
+  return { header, results };
+}
+
+export default {
+    export_table_to_excel,
+    export_array_to_excel,
+    export_json_to_excel,
+    read
+}

+ 51 - 30
TEAMModelOS/ClientApp/view/school-mgmt/ClassroomSetting/ClassroomSetting.less

@@ -187,7 +187,7 @@
     color:@third-textColor;
 }
 .fourth-text-color {
-    color: #ED4014 !important;
+    color: #6BDFC3 !important;
     /*text-shadow:1px 1px 1px white;*/
 }
 .class-hiteach-code {
@@ -237,49 +237,70 @@
     top: 50px;
     bottom: 0px;
     left: 47%;
+
     &-header {
         width: ~"calc(100% - 30px)";
         -moz-width: ~"calc(100% - 30px)";
         -webkit-width: ~"calc(100% - 30px)";
-        margin-left:30px;
-        p{
-            padding:10px 0px;
-            color:@second-textColor;
+        margin-left: 20px;
+
+        p {
+            padding: 10px 0px;
+            color: @second-textColor;
             .border(bottom);
         }
     }
-    &-list{
+
+    &-list {
         .border(top);
-        position:absolute;
-        left:0px;
-        top:70px;
-        bottom:0px;
-        width:100%;
+        position: absolute;
+        left: 0px;
+        top: 70px;
+        bottom: 0px;
+        width: 100%;
         /*display:flex;
         justify-content:center;
         align-items:center;*/
-
-        h1{
-            margin-top:-120px;
+        h1 {
+            margin-top: -120px;
         }
-        ul{
-            list-style:none;
-            padding-left:20px;
-            margin-top:15px;
-            li{
-                &:hover{
-                    background:@borderColor;
-                    color:white;
+
+        ul {
+            list-style: none;
+            padding-left: 20px;
+            margin-top: 15px;
+
+            li {
+                span {
+                    text-overflow: ellipsis;
+                    overflow: hidden;
+                    white-space: nowrap;
+                    display: inline-block;
+                    width: -moz-calc(100% - 50px);
+                    width: -webkit-calc(100% - 50px);
+                    width: calc(100% - 50px);
                 }
-                height:40px;
-                line-height:40px;
-                color:@second-textColor;
-                font-size:@second-fontSize - 1;
-                padding-left:15px;
-                cursor:pointer;
+
+                &:hover {
+                    background: @borderColor;
+                    color: white;
+                }
+
+                height: 40px;
+                line-height: 40px;
+                color: @second-textColor;
+                font-size: @second-fontSize - 1;
+                padding-left: 5px;
+                cursor: pointer;
                 .border(bottom);
-                .ivu-icon{
-                    margin-top:-4px;
+
+                .ivu-icon {
+                    margin-top: -4px;
+                }
+
+                .ivu-tag {
+                    float: right;
+                    margin-top: 8px;
                 }
             }
         }

+ 66 - 62
TEAMModelOS/ClientApp/view/school-mgmt/ClassroomSetting/ClassroomSetting.vue

@@ -112,7 +112,7 @@
                 </p>
               </div>
               <div class="class-list-item-tool">
-                <Icon type="ios-copy" title="不知道" />
+                <!--<Icon type="ios-copy" title="复制" />-->
                 <Icon type="md-trash" title="删除" @click.stop="delClassroom(index)" />
               </div>
             </div>
@@ -132,11 +132,11 @@
             <Input v-model="classroomList[currentClassroomIndex].headMaster" placeholder="请输入指定教师名称..." />
             <span class="class-attr-wrap-label">选择教室学段</span>
             <Select v-model="classroomList[currentClassroomIndex].period">
-              <Option v-for="(item,index) in periodList" :value="item.value" :key="index">{{ item.value }}</Option>
+              <Option v-for="(item,index) in periodList" :value="item.code" :key="index" @click.native="currentPIndex = index">{{ item.name }}</Option>
             </Select>
             <span class="class-attr-wrap-label">选择教室年级</span>
             <Select v-model="classroomList[currentClassroomIndex].grade">
-              <Option v-for="(item,index) in gradeList" :value="item.value" :key="index">{{ item.value }}</Option>
+              <Option v-for="(item,index) in periodList[currentPIndex].grade" :value="item.code" :key="index">{{ item.name }}</Option>
             </Select>
             <span class="class-attr-wrap-label">HiTeach软件序号</span>
             <Input v-model="classroomList[currentClassroomIndex].hiTeach" disabled placeholder="请在右侧列表选择可用序号..." />
@@ -155,12 +155,9 @@
             <div class="hiteach-code-wrap-list">
               <h1 v-if="!hiTeachs.length">没有序号登录</h1>
               <ul v-else>
-                <li v-for="(item,index) in hiTeachsShow" :key="index" @click="chooseHiTeach(index)" :class="item.using > 0 ? 'fourth-text-color':''">
-                  {{item.code}}
-                  <Icon type="ios-star" color="white" v-if="item.single == 1 && item.using <= 0" />
-                  <Badge :count="item.using" v-if="item.single == 1 && item.using > 0">
-
-                  </Badge>
+                <li v-for="(item,index) in hiTeachsShow" :key="index" @click="chooseHiTeach(index)" :class="item.using > 0 ? 'fourth-text-color':''" :title="item.code">
+                  <span>{{item.code}}</span>
+                  <Tag color="#6BDFC3" v-if="item.single == 1">{{item.using+'/'+5}}</Tag>
                 </li>
               </ul>
             </div>
@@ -213,6 +210,7 @@
   export default {
     data() {
       return {
+        currentPIndex:0,
         demoLoginInfo: {
           user: "admin",
           teamModelId: "habook#0001",
@@ -297,9 +295,33 @@
             using:0
           }
         ],
-        classroomList: [],
+        classroomList: [{
+          name: '预设教室',
+          hiTeach: '',
+          headMaster: '未指定班主任',
+          period: '', 
+          grade: '',
+          stuNum: 0,
+          classroomType: 'TEAM MODEL智慧教室',
+          classroomCode: '教室编码',
+          point: {
+            x: 5,
+            y: 5
+          }
+        }],
         classroomListShow: [],
-        periodList: [],
+        periodList: [
+          {
+            name: '暂无学段信息',
+            code: "",
+            grade: [
+              {
+                name: '暂无年级信息',
+                code: ""
+              }
+            ]
+          }
+        ],
         gradeList: [],
         currentClassroomIndex: 0,
         schoolPlan: '',
@@ -593,6 +615,7 @@
         return false;
       },
       saveClassroom() {
+        this.classroomList[this.currentClassroomIndex]["schoolCode"] = this.demoLoginInfo.schoolCode;
         this.$api.schoolSetting.classroomSettingSaveOrUpdate(this.classroomList[this.currentClassroomIndex]).then(res => {
           if (res.error == null) {
             this.$Message.success('保存成功!');
@@ -600,6 +623,19 @@
           }
         });
       },
+      getClassroom() {
+        this.$api.schoolSetting.findClassInfo({
+          SchoolCode: this.demoLoginInfo.schoolCode
+        }).then(res => {
+          if (res.error == null) {
+            if (res.result.data.length > 0) {
+              this.classroomList = res.result.data;
+              this.filterClassname();
+            }
+          }
+        });
+
+      },
       delClassroom(index) {
         if (this.currentClassroomIndex >= index && index > 0) {
           this.currentClassroomIndex = 0;
@@ -685,6 +721,12 @@
         }
         this.filterCode();
       },
+      guid() {
+        function S4() {
+          return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
+        }
+        return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
+      },
       initData() {
         let white = new Image();
         let pink = new Image();
@@ -705,57 +747,15 @@
         green.onload = function () {
           _this.greenImageData = green;
         }
-        this.classroomList.push({
-          name: '预设教室' + (this.classroomList.length + 1),
-          hiTeach: '',
-          headMaster: '未指定班主任',
-          period: '',
-          grade: '',
-          stuNum: 0,
-          classroomType: 'TEAM MODEL智慧教室',
-          classroomCode: '教室编码',
-          point: {
-            x: 5,
-            y: 5
+        this.$api.schoolSetting.findSchoolSystem({
+          Code: this.demoLoginInfo.schoolCode
+        }).then(res => {
+          if (res.error == null) {
+            if (res.result.data.length > 0) {
+              this.periodList = res.result.data[0].period;
+            }
           }
         });
-        this.periodList = [
-          {
-            value: '小学'
-          },
-          {
-            value: '初中'
-          },
-          {
-            value: '高中'
-          },
-          {
-            value: '职中'
-          },
-          {
-            value: '高等教育'
-          }
-        ];
-        this.gradeList = [
-          {
-            value: '一年级'
-          },
-          {
-            value: '二年级'
-          },
-          {
-            value: '三年级'
-          },
-          {
-            value: '四年级'
-          },
-          {
-            value: '五年级'
-          },
-          {
-            value: '六年级'
-          }
-        ]
       },
       addClassroom() {
         this.serchClassName = '';
@@ -778,14 +778,17 @@
       }
     },
     mounted() {
-      this.drawSchoolPlan();
+      
       let _this = this;
       setTimeout(function () {
+        _this.drawSchoolPlan();
+        _this.bundleScoll();
         _this.initIcon();
       }, 1000);
       this.filterClassname();
       this.filterCode();
-      this.bundleScoll();
+      
+      
     },
     beforeRouteLeave(to, from, next) {
       if (this.updated) {
@@ -825,6 +828,7 @@
       }
     },
     created() {
+      this.getClassroom();
       this.initData();
     }
   }

+ 92 - 97
TEAMModelOS/ClientApp/view/school-mgmt/SystemSetting/SystemSetting.vue

@@ -44,7 +44,7 @@
           <span>依建立时间排序</span>
         </div>
         <div class="period-list">
-          <div class="period-item" v-for="(item,index) in schoolSetting.systems" :key="index" @click="choosePeriod(index)" :class="index == currentSchoolSysIndex ? 'item-active-div':''">
+          <div class="period-item" v-for="(item,index) in schoolSetting.period" :key="index" @click="choosePeriod(index)" :class="index == currentSchoolSysIndex ? 'item-active-div':''">
             <p class="period-item-name">
               <EditableLabel ref="periodName" class="term-item-name" :content="item.name" @editComplete="handleEditPeriod($event,index)">
               </EditableLabel>
@@ -66,9 +66,9 @@
           <Icon type="md-add" @click="handleAddTerm" />
         </div>
         <div class="col-body">
-          <div class="no-data-text" v-if="!schoolSetting.systems[currentSchoolSysIndex].semester.length">没有设置学期</div>
-          <div class="term-list" v-if="schoolSetting.systems[currentSchoolSysIndex].semester.length">
-            <div class="term-item editable" v-for="(item,index) in schoolSetting.systems[currentSchoolSysIndex].semester" :key="index" :class="index == currentSemesterIndex ? 'item-active-div':''" @click="chooseSemester(index)">
+          <div class="no-data-text" v-if="!schoolSetting.period[currentSchoolSysIndex].semester.length">没有设置学期</div>
+          <div class="term-list" v-if="schoolSetting.period[currentSchoolSysIndex].semester.length">
+            <div class="term-item editable" v-for="(item,index) in schoolSetting.period[currentSchoolSysIndex].semester" :key="index" :class="index == currentSemesterIndex ? 'item-active-div':''" @click="chooseSemester(index)">
               <span class="term-item-name-line" :style="{backgroundColor: colorList[index]}"></span>
               <EditableLabel ref="semesterName" class="term-item-name" :content="item.name" @editComplete="handleEditSemester($event,index)">
               </EditableLabel>
@@ -95,18 +95,18 @@
               <li v-for="(item,index) in monthEnList" :key="index">
                 <span class="time-label">{{item}}.</span>
                 <span class="time-dot">
-                  <span v-if="auto" class="time-inner-dot" :class="index + 1 >= schoolSetting.systems[currentSchoolSysIndex].semester[currentSemesterIndex].month && index < endMonth ? 'bg-color-check':'bg-color-uncheck'"></span>
-                  <span v-else class="time-inner-dot" :class="index + 1 >= schoolSetting.systems[currentSchoolSysIndex].semester[currentSemesterIndex].month || index < endMonth ? 'bg-color-check':'bg-color-uncheck'"></span>
+                  <span v-if="auto" class="time-inner-dot" :class="index + 1 >= schoolSetting.period[currentSchoolSysIndex].semester[currentSemesterIndex].month && index < endMonth ? 'bg-color-check':'bg-color-uncheck'"></span>
+                  <span v-else class="time-inner-dot" :class="index + 1 >= schoolSetting.period[currentSchoolSysIndex].semester[currentSemesterIndex].month || index < endMonth ? 'bg-color-check':'bg-color-uncheck'"></span>
                   <span class="time-line-tail"></span>
                 </span>
                 <div>
-                  <Icon class="first-arrow" size="22" type="ios-arrow-back" v-if="index + 1 == schoolSetting.systems[currentSchoolSysIndex].semester[currentSemesterIndex].month || index + 1 == endMonth" />
-                  <!--<Icon class="second-arrow" size="22" :class="index  < endMonth ? 'color-check':'color-uncheck'" type="ios-arrow-back" v-if="index + 1 == schoolSetting.systems[currentSchoolSysIndex].semester[currentSemesterIndex].month || index + 1 == endMonth" />-->
+                  <Icon class="first-arrow" size="22" type="ios-arrow-back" v-if="index + 1 == schoolSetting.period[currentSchoolSysIndex].semester[currentSemesterIndex].month || index + 1 == endMonth" />
+                  <!--<Icon class="second-arrow" size="22" :class="index  < endMonth ? 'color-check':'color-uncheck'" type="ios-arrow-back" v-if="index + 1 == schoolSetting.period[currentSchoolSysIndex].semester[currentSemesterIndex].month || index + 1 == endMonth" />-->
                   <span v-if="auto">
-                    <Icon class="second-arrow" size="22" :class="index  < endMonth ? 'color-check':'color-uncheck'" type="ios-arrow-back" v-if="index + 1 == schoolSetting.systems[currentSchoolSysIndex].semester[currentSemesterIndex].month || index + 1 == endMonth" />
+                    <Icon class="second-arrow" size="22" :class="index  < endMonth ? 'color-check':'color-uncheck'" type="ios-arrow-back" v-if="index + 1 == schoolSetting.period[currentSchoolSysIndex].semester[currentSemesterIndex].month || index + 1 == endMonth" />
                   </span>
                   <span v-else>
-                    <Icon class="second-arrow" size="22" :class="index + 1 >= endMonth ? 'color-check':'color-uncheck'" type="ios-arrow-back" v-if="index + 1 == schoolSetting.systems[currentSchoolSysIndex].semester[currentSemesterIndex].month || index + 1 == endMonth" />
+                    <Icon class="second-arrow" size="22" :class="index + 1 >= endMonth ? 'color-check':'color-uncheck'" type="ios-arrow-back" v-if="index + 1 == schoolSetting.period[currentSchoolSysIndex].semester[currentSemesterIndex].month || index + 1 == endMonth" />
                   </span>
                 </div>
               </li>
@@ -123,7 +123,7 @@
           </div>
         </div>
         <div class="grade-body">
-          <div class="grade-item item-active" v-for="(item,index) in schoolSetting.systems[currentSchoolSysIndex].grade" :key="index">
+          <div class="grade-item item-active" v-for="(item,index) in schoolSetting.period[currentSchoolSysIndex].grade" :key="index">
             <span class="grade-item-icon"></span>
             <EditableLabel ref="gradeName" class="grade-item-name" :content="item.name" @editComplete="handleEditGrade($event,index)">
             </EditableLabel>
@@ -139,7 +139,7 @@
           </div>
         </div>
         <div class="grade-body">
-          <div class="grade-item item-active" v-for="(item,index) in schoolSetting.systems[currentSchoolSysIndex].subject" :key="index">
+          <div class="grade-item item-active" v-for="(item,index) in schoolSetting.period[currentSchoolSysIndex].subject" :key="index">
             <span class="grade-item-icon"></span>
             <EditableLabel ref="subjectName" class="grade-item-name" :content="item.name" @editComplete="handleEditSubject($event,index)">
             </EditableLabel>
@@ -149,9 +149,6 @@
         </div>
       </div>
     </div>
-    <!--<Modal v-model="updated">
-      <p>您修改信息后还未保存,如果离开数据将会丢失!</p>
-    </Modal>-->
   </div>
 
 </template>
@@ -186,24 +183,7 @@
         schoolSetting: {
           code: "",
           name: "",
-          systems: [
-            {
-              name: "预设学段1",
-              gradeCount: 0,
-              semesterCount: 0,
-              subjectCount: 0,
-              semester: [
-                {
-                  name: "预设学期1",
-                  studentCount: "学生人数",
-                  month: 1,
-                  day:26
-                }
-              ],
-              grade: [],
-              subject: []
-            }
-          ]
+          period: []
         },
         tabIndex: 0,
         periodList: [
@@ -228,29 +208,29 @@
     methods: {
       //删除节点
       delGrade(index) {
-        this.schoolSetting.systems[this.currentSchoolSysIndex].grade.splice(index, 1);
+        this.schoolSetting.period[this.currentSchoolSysIndex].grade.splice(index, 1);
       },
       delSubject(index) {
-        this.schoolSetting.systems[this.currentSchoolSysIndex].subject.splice(index, 1);
+        this.schoolSetting.period[this.currentSchoolSysIndex].subject.splice(index, 1);
       },
       delPeriod(index) {
         if (this.currentSchoolSysIndex >= index && index > 0) {
           this.currentSemesterIndex = 0;
           this.currentSchoolSysIndex = 0;
         }
-        if (this.schoolSetting.systems.length > 1) {
+        if (this.schoolSetting.period.length > 1) {
           this.currentSchoolSysIndex = 0;
           this.currentSemesterIndex = 0;
-          this.schoolSetting.systems.splice(index, 1);
+          this.schoolSetting.period.splice(index, 1);
         } else {
           this.$Message.warning('至少需要保留一项!');
         }
       },
       delSemester(index) {
-        if (this.schoolSetting.systems[this.currentSchoolSysIndex].semester.length > 1) {
+        if (this.schoolSetting.period[this.currentSchoolSysIndex].semester.length > 1) {
           this.currentSchoolSysIndex = 0;
           this.currentSemesterIndex = 0;
-          this.schoolSetting.systems[this.currentSchoolSysIndex].semester.splice(index, 1);
+          this.schoolSetting.period[this.currentSchoolSysIndex].semester.splice(index, 1);
         } else {
           this.$Message.warning('至少需要保留一项!');
         }
@@ -258,30 +238,41 @@
       initData() {
         this.schoolSetting.code = this.demoLoginInfo.schoolCode;
         this.schoolSetting.name = this.demoLoginInfo.school;
-        this.schoolSetting.systems[0].grade.push({
+        this.schoolSetting.period.push({
+          name: "预设学段1",
+          code: this.guid(),
+          gradeCount: 0,
+          semesterCount: 0,
+          subjectCount: 0,
+          semester: [],
+          grade: [],
+          subject: []
+        });
+        this.schoolSetting.period[0].grade.push({
           name: '一年级',
           code: this.guid()
         });
-        this.schoolSetting.systems[0].grade.push({
+        this.schoolSetting.period[0].grade.push({
           name: '二年级',
           code: this.guid()
         });
-        this.schoolSetting.systems[0].grade.push({
+        this.schoolSetting.period[0].grade.push({
           name: '三年级',
           code: this.guid()
         });
-        this.schoolSetting.systems[0].subject.push({
+        this.schoolSetting.period[0].subject.push({
           name: '语文',
           code: this.guid()
         });
-        this.schoolSetting.systems[0].subject.push({
+        this.schoolSetting.period[0].subject.push({
           name: '数学',
           code: this.guid()
         });
-        this.schoolSetting.systems[0].subject.push({
+        this.schoolSetting.period[0].subject.push({
           name: '英语',
           code: this.guid()
         });
+        this.updated = false;
       },
       changeGradeEditStatus(index) {
         this.$refs.gradeName[index].handleEdit();
@@ -314,21 +305,24 @@
           if (res.error == null) {
             if (res.result.data.length > 0) {
               this.schoolSetting = res.result.data[0];
+              this.updated = false;
+            } else {
+              this.initData();
             }
           }
         }
         );
       },
       handleData() {
-        for (let i = 0; i < this.schoolSetting.systems.length; i++) {
-          this.schoolSetting.systems[i].gradeCount = this.schoolSetting.systems[i].grade.length;
-          this.schoolSetting.systems[i].semesterCount = this.schoolSetting.systems[i].semester.length;
-          this.schoolSetting.systems[i].subjectCount = this.schoolSetting.systems[i].subject.length;
+        for (let i = 0; i < this.schoolSetting.period.length; i++) {
+          this.schoolSetting.period[i].gradeCount = this.schoolSetting.period[i].grade.length;
+          this.schoolSetting.period[i].semesterCount = this.schoolSetting.period[i].semester.length;
+          this.schoolSetting.period[i].subjectCount = this.schoolSetting.period[i].subject.length;
         }
       },
       handleEditGrade(val, index) {
         let flag = false;
-        this.schoolSetting.systems[this.currentSchoolSysIndex].grade.forEach((v, i) => {
+        this.schoolSetting.period[this.currentSchoolSysIndex].grade.forEach((v, i) => {
           if (v.name == val) {
             flag = true;
           }
@@ -336,13 +330,13 @@
         if (flag) {
           this.$Message.warning('已有相同的名字,请重新设置名字!');
         } else {
-          this.schoolSetting.systems[this.currentSchoolSysIndex].grade[index].name = val;
+          this.schoolSetting.period[this.currentSchoolSysIndex].grade[index].name = val;
         }
         
       },
       handleEditSubject(val, index) {
         let flag = false;
-        this.schoolSetting.systems[this.currentSchoolSysIndex].subject.forEach((v, i) => {
+        this.schoolSetting.period[this.currentSchoolSysIndex].subject.forEach((v, i) => {
           if (v.name == val) {
             flag = true;
           }
@@ -350,7 +344,7 @@
         if (flag) {
           this.$Message.warning('已有相同的名字,请重新设置名字!');
         } else {
-          this.schoolSetting.systems[this.currentSchoolSysIndex].subject[index].name = val;
+          this.schoolSetting.period[this.currentSchoolSysIndex].subject[index].name = val;
         }
       },
       handleEditSchoolName(val) {
@@ -358,7 +352,7 @@
       },
       handleEditPeriod(val, index) {
         let flag = false;
-        this.schoolSetting.systems.forEach((v, i) => {
+        this.schoolSetting.period.forEach((v, i) => {
           if (v.name == val) {
             flag = true;
           }
@@ -366,12 +360,12 @@
         if (flag) {
           this.$Message.warning('已有相同的名字,请重新设置名字!');
         } else {
-          this.schoolSetting.systems[index].name = val;
+          this.schoolSetting.period[index].name = val;
         }
       },
       handleEditSemester(val, index) {
         let flag = false;
-        this.schoolSetting.systems[this.currentSchoolSysIndex].semester.forEach((v, i) => {
+        this.schoolSetting.period[this.currentSchoolSysIndex].semester.forEach((v, i) => {
           if (v.name == val) {
             flag = true;
           }
@@ -379,7 +373,7 @@
         if (flag) {
           this.$Message.warning('已有相同的名字,请重新设置名字!');
         } else {
-          this.schoolSetting.systems[this.currentSchoolSysIndex].semester[index].name = val;
+          this.schoolSetting.period[this.currentSchoolSysIndex].semester[index].name = val;
         }
       },
       changePeriodEditStatus(index) {
@@ -394,8 +388,8 @@
       addSubject() {
         if (this.termList.length < this.TERM_MAX_LENGTH) {
           let newTerm = Object.assign({}, defaultTerm);
-          this.schoolSetting.systems[this.currentSchoolSysIndex].subject.push({
-            name: "预设学科"+(this.schoolSetting.systems[this.currentSchoolSysIndex].subject.length+1),
+          this.schoolSetting.period[this.currentSchoolSysIndex].subject.push({
+            name: "预设学科"+(this.schoolSetting.period[this.currentSchoolSysIndex].subject.length+1),
             code:this.guid()
           });
         } else {
@@ -411,8 +405,8 @@
       addGrade() {
         if (this.termList.length < this.TERM_MAX_LENGTH) {
           let newTerm = Object.assign({}, defaultTerm);
-          this.schoolSetting.systems[this.currentSchoolSysIndex].grade.push({
-            name: "预设年级"+(this.schoolSetting.systems[this.currentSchoolSysIndex].grade.length),
+          this.schoolSetting.period[this.currentSchoolSysIndex].grade.push({
+            name: "预设年级"+(this.schoolSetting.period[this.currentSchoolSysIndex].grade.length),
             code:this.guid()
           });
         } else {
@@ -420,32 +414,33 @@
         }
       },
       addPeriod() {
-        this.schoolSetting.systems.push({
-              name: "预设学段"+(this.schoolSetting.systems.length+1),
-              gradeCount: 0,
-              semesterCount: 0,
-              subjectCount: 0,
-              semester: [
-                {
-                  name: "预设学期1",
-                  studentCount: "学生人数",
-                  month: this.schoolSetting.systems[this.currentSchoolSysIndex].semester[this.currentSemesterIndex].month + 1,
-                  day:26
-                }
-              ],
-              grade: [
-                {
-                  code: "年级编码",
-                  name: "预设年级1"
-                }
-              ],
-              subject: [
-                {
-                  code: "科目编码",
-                  name: "预设科目1"
-                }
-              ]
-            });
+        this.schoolSetting.period.push({
+          name: "预设学段" + (this.schoolSetting.period.length + 1),
+          code: this.guid(),
+          gradeCount: 0,
+          semesterCount: 0,
+          subjectCount: 0,
+          semester: [
+            {
+              name: "预设学期1",
+              studentCount: "学生人数",
+              month: this.schoolSetting.period[this.currentSchoolSysIndex].semester[this.currentSemesterIndex].month + 1,
+              day: 26
+            }
+          ],
+          grade: [
+            {
+              code: "年级编码",
+              name: "预设年级1"
+            }
+          ],
+          subject: [
+            {
+              code: "科目编码",
+              name: "预设科目1"
+            }
+          ]
+        });
       },
       //获取随机颜色十六进制
       getRandomColor() {
@@ -455,10 +450,10 @@
       handleAddTerm() {
         if (this.termList.length < this.TERM_MAX_LENGTH) {
           let newTerm = Object.assign({}, defaultTerm);
-          this.schoolSetting.systems[this.currentSchoolSysIndex].semester.push({
-            name: "预设学期"+(this.schoolSetting.systems[this.currentSchoolSysIndex].semester.length+1),
+          this.schoolSetting.period[this.currentSchoolSysIndex].semester.push({
+            name: "预设学期"+(this.schoolSetting.period[this.currentSchoolSysIndex].semester.length+1),
             studentCount: "学生人数",
-            month: this.schoolSetting.systems[this.currentSchoolSysIndex].semester[this.currentSemesterIndex].month + 1,
+            month: this.schoolSetting.period[this.currentSchoolSysIndex].semester[this.currentSemesterIndex].month + 1,
             day: 26
           });
         } else {
@@ -507,10 +502,10 @@
       }
     },
     created() {
-      this.initData();
+      
     },
     beforeRouteLeave(to, from, next) {
-      if (this.updated) {
+      if (this.updated == true) {
         let config = {
           render: (h) => {
             return h("h3", {
@@ -547,14 +542,14 @@
     computed: {
       endMonth() {
         let end = 1;
-        if(this.schoolSetting.systems[this.currentSchoolSysIndex].semester.length == 1){
+        if(this.schoolSetting.period[this.currentSchoolSysIndex].semester.length == 1){
           end = 12;
           this.auto = true;
-        } else if (this.currentSemesterIndex + 1 < this.schoolSetting.systems[this.currentSchoolSysIndex].semester.length) {
-          end = this.schoolSetting.systems[this.currentSchoolSysIndex].semester[this.currentSemesterIndex + 1].month;
+        } else if (this.currentSemesterIndex + 1 < this.schoolSetting.period[this.currentSchoolSysIndex].semester.length) {
+          end = this.schoolSetting.period[this.currentSchoolSysIndex].semester[this.currentSemesterIndex + 1].month;
           this.auto = true;
-        } else if (this.currentSemesterIndex + 1 == this.schoolSetting.systems[this.currentSchoolSysIndex].semester.length){
-          end = this.schoolSetting.systems[this.currentSchoolSysIndex].semester[0].month;
+        } else if (this.currentSemesterIndex + 1 == this.schoolSetting.period[this.currentSchoolSysIndex].semester.length){
+          end = this.schoolSetting.period[this.currentSchoolSysIndex].semester[0].month;
           this.auto = false;
         }
         return end;

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

@@ -0,0 +1,82 @@
+@first-bgColor:#141414; 
+@second-bgColor:#1b1b1b;
+@third-bgColor:#222222; 
+@borderColor: #424242;
+@primary-textColor:#fff; //文本主颜色
+@second-textColor:#a5a5a5; //文本副级颜色
+@primary-fontSize:14px;
+@second-fontSize:16px;
+
+.sc {
+    &-container {
+        width: 100%;
+        height: 100%;
+        background-color: @first-bgColor;
+        padding-top: 60px;
+    }
+
+    &-menu {
+        height: 45px;
+        width: ~"calc(100%-50px)";
+        width: ~"-webkit-calc(100%-50px)";
+        width: ~"-moz-calc(100%-50px)";
+        border-bottom: 1px solid @borderColor;
+        border-top: 1px solid @borderColor;
+        padding: 0px 35px 0px 15px;
+        box-sizing: content-box;
+        -webkit-box-sizing: content-box;
+        -moz-box-sizing: content-box;
+        background-color: @second-bgColor;
+
+        &-left {
+            float: left;
+            line-height: 45px;
+            height: 45px;
+            width: 66%;
+        }
+
+        &-right {
+            float: right;
+            line-height: 45px;
+            height: 45px;
+            width: 34%;
+
+            ul {
+                list-style: none;
+                color: @second-textColor;
+                width: 100%;
+
+                li {
+                    height: 45px;
+                    line-height: 45px;
+                    display: inline-block;
+                    margin-left: 30px;
+                    float: right;
+                    cursor: pointer;
+                }
+
+                span {
+                    margin-left: 8px;
+                    display: inline-block;
+                }
+            }
+        }
+    }
+
+    &-content {
+        width: 100%;
+        height: ~"calc(100% - 80px)";
+        padding-left: 35px;
+    }
+
+    &-text-no-select {
+        -webkit-user-select: none;
+        -moz-user-select: none;
+        -ms-user-select: none;
+        user-select: none;
+    }
+}
+
+.item-tools{
+    display:none;
+}

+ 282 - 0
TEAMModelOS/ClientApp/view/student-account/Index.vue

@@ -0,0 +1,282 @@
+<style lang="less" scoped>
+  @import './Index.less';
+</style>
+<style lang="less">
+  @import './IndexIview.less';
+</style>
+
+<template>
+  <div class="sc-container">
+    <div class="sc-menu">
+      <div class="sc-menu-left">
+        <Input v-model="serchText" clearable placeholder="请输入关键字或账号资讯..." style="width: 28%;margin-left:20px;" :search="true"  @on-enter="searchData" @on-search="searchData" @on-clear="searchData">
+        <!--<Icon type="ios-search" color="white" slot="suffix" style="cursor:pointer;"/>-->
+        </Input>
+        <Select v-model="model" style="width:20%;margin-left:5%;" placeholder="所在学制" clearable>
+          <Option v-for="item in list" :value="item.value" :key="item.value">{{ item.label }}</Option>
+        </Select>
+        <Select v-model="model" style="width:20%;margin-left:1%;" placeholder="所在学制" clearable>
+          <Option v-for="item in list" :value="item.value" :key="item.value">{{ item.label }}</Option>
+        </Select>
+        <Select v-model="model" style="width:20%;margin-left:1%;" placeholder="所在学制" clearable>
+          <Option v-for="item in list" :value="item.value" :key="item.value">{{ item.label }}</Option> 
+        </Select>
+      </div>
+      <div class="sc-menu-right sc-text-no-select">
+        <ul>
+          <li @click="importStudent()">
+            <Icon type="md-arrow-round-up" color="white" size="18" />
+            <span>汇入名单</span>
+          </li>
+          <li @click="delStudent(-1)">
+            <Icon type="md-trash" color="white" size="18" />
+            <span>删除学生</span>
+          </li>
+          <li @click="editStudent()">
+            <Icon type="md-create" color="white" size="18" />
+            <span>编辑资讯</span>
+          </li> 
+          <li @click="addStudent()">
+            <Icon type="md-person-add" color="white" size="18" />
+            <span>新增学生</span>
+          </li>
+          <li @click="showAuthorization()">
+            <Icon type="ios-cog-outline" color="white" size="18" />
+            <span>授权管理</span>
+          </li>
+        </ul>
+      </div>
+    </div>
+    <div class="sc-content" style="position:relative">
+      <Table ref="selection" :columns="tableColumns" :data="tablePageData" height="750" :loading="tableLoading" @on-select="getSelectInfo" @on-select-cancel="getSelectInfo" @on-select-all="getSelectInfo" @on-select-all-cancel="cancelAll">
+        <template slot-scope="{ row,index }" slot="status">
+          <Icon v-if="row.status == 1" type="md-checkmark-circle-outline" size="18" color="#1CD0A1" />
+          <Icon v-else type="md-close" size="18" color="red" />
+        </template>
+        <template slot-scope="{ row,index }" slot="action">
+          <div class="item-tools">
+            <Icon type="md-create" size="18" color="white" @click="editStudent(index)" />
+            <Icon type="md-trash" size="18" color="white" @click="delStudent(index)" />
+          </div>
+        </template>
+      </Table>
+      <Page :total="tableShowData.length" size="small" :page-size="pageSize" show-total style="margin-top:15px;" :current.sync="currentPage" @on-change="getPageData"/>
+      <authorization :isShow="authorizationStatus" @closeAuth="closeAuth"></authorization>
+    </div>
+    <add-student :schoolCode="demoLoginInfo.schoolCode" :isShow="addStudentStatus" :editStudentInfo="editStudentInfo" @saveStudentInfo="closeAddStudent" :bizType="bizType"></add-student>
+    <import-student :schoolCode="demoLoginInfo.schoolCode" :isShow="importStudentStatus" @importStudentInfo="closeImportStudent"></import-student>
+    
+  </div>
+</template>
+
+<script>
+  import AddStudent from "./add-student/AddStudent"
+  import ImportStudent from "./add-student/ImportStudent"
+  import Authorization from "./add-student/Authorization"
+  export default {
+    components: {
+      AddStudent,
+      ImportStudent,
+      Authorization
+    },
+    data() {
+      return {
+        tableLoading: false,
+        serchText:'',
+        currentPage:1,
+        pageSize:30,
+        bizType:0,
+        editStudentInfo:[],
+        selctions: [],
+        selectRow: {},
+        addStudentStatus:false,
+        importStudentStatus: false,
+        authorizationStatus: false,
+        demoLoginInfo: {
+          user: "admin",
+          teamModelId: "habook#0001",
+          school: "醍摩豆书院",
+          schoolCode:"101010"
+        },
+        model: "",
+        list: [],
+        tableData: [],
+        tableShowData: [],
+        tablePageData:[],
+        tableColumns: [
+          {
+            type: 'selection',
+            width: 80,
+            align: 'center'
+          },
+          {
+            key: "account",
+            title:"账号资讯",
+            align: 'center'
+          },
+          {
+            key: "name",
+            title:"名称",
+            align: 'center'
+          },
+          {
+            key: "classroom",
+            title:"教室资讯",
+            align: 'center'
+          },
+          {
+            key: "period",  
+            title:"学制资讯",
+            align: 'center'
+          },
+          {
+            key: "grade",
+            title:"学级",
+            align: 'center'
+          },
+          {
+            slot: "status",
+            title:"授权状态",
+            align: 'center'
+          },
+          {
+            slot: "action",
+            title: " ",
+            width:100,
+            align: 'center'
+          }
+        ]
+      }
+    },
+    methods: {
+      getPageData() {
+        let start = ((this.currentPage - 1) * this.pageSize);
+        let end = 0;
+        if (this.tableShowData.length < this.currentPage * this.pageSize) {
+          end = this.tableShowData.length;
+        } else {
+          end = this.currentPage * this.pageSize;
+        }
+        this.tablePageData = this.tableShowData.slice(start, end);
+      },
+      searchData() {
+        this.tableLoading = true;
+        this.tableShowData = this.tableData.filter(item => item.account.indexOf(this.serchText) != -1);
+        this.currentPage = 1;
+        this.getPageData();
+        this.tableLoading = false;
+      },
+      cancelAll() {
+        this.selctions = [];
+      },
+      getIndex(_arr, _obj) {
+        var len = _arr.length;
+        for (let i = 0; i < len; i++) {
+          if (this.isObjEqual(_arr[i],_obj)) {
+            return parseInt(i);
+          }
+        }
+        return -1;
+      },
+      isObjEqual(o1, o2) {
+        var props1 = Object.keys(o1);
+        var props2 = Object.keys(o2);
+        console.log(props1);
+        if (props1.length != props2.length) {
+          return false;
+        }
+        for (var i = 0, max = props1.length; i < max; i++) {
+          var propName = props1[i];
+          if (o1[propName] !== o2[propName]) {
+            return false;
+          }
+        }
+        return true;
+      },
+      getSelectInfo(selction, row) {
+        console.log(this.tableData);
+        this.selctions = selction;
+        this.selectRow = row;
+      },
+      closeAddStudent(data) {
+        if (data.action == 1) {
+          let infoString = JSON.stringify(data.studentInfo);
+          let info = JSON.parse(infoString); 
+          info.account = this.demoLoginInfo.schoolCode + "#" + info.account;
+          this.tableData.unshift(info);
+          [...this.tableShowData] = this.tableData;
+          this.getPageData();
+        }
+        this.addStudentStatus = false;
+      },
+      closeImportStudent(data) {
+        this.importStudentStatus = false;
+        console.log(data);
+        this.tableData.push(...(data.data));
+        [...this.tableShowData] = this.tableData;
+        this.getPageData();
+        console.log(this.tableData);
+      },
+      closeAuth() {
+        this.authorizationStatus = false;
+      },
+      addStudent() {
+        this.bizType = 1;
+        this.$refs.selection.clearCurrentRow();
+        this.addStudentStatus = true;
+        
+      },
+      importStudent() {
+        this.importStudentStatus = true;
+      },
+      showAuthorization() {
+        this.authorizationStatus = true;
+      },
+      editStudent(index) {
+        this.bizType = 2;
+        if (index != undefined) {
+          this.editStudentInfo = [];
+          let objStr = JSON.stringify(this.tableData[index]);
+          this.editStudentInfo.push(JSON.parse(objStr));
+          this.tableShowData[index]._checked = true;
+          this.tablePageData[index]._checked = true;
+          this.$forceUpdate();
+          this.addStudentStatus = true;
+        } else {
+          if (this.selctions.length > 0) {
+            
+            this.editStudentInfo = [];
+            [...this.editStudentInfo] = this.selctions;
+            this.addStudentStatus = true;
+          } else {
+            this.$Message.error('请选择需要修改的学生!');
+          }
+        }
+        
+      },
+      delStudent(index, row) {
+        if (index >= 0) {
+          let showIndex = index + (this.currentPage - 1) * this.pageSize;
+          let originIndex = this.getIndex(this.tableData, this.tablePageData[index]);
+          this.tableData.splice(originIndex, 1);
+          this.tablePageData.splice(index, 1);
+          this.tableShowData.splice(showIndex, 1);
+        } else {
+          let i = this.getIndex(this.tableData, row);
+          if (i >= 0) {
+            this.tableData.splice(i, 1);
+          } else {
+             this.$Message.error('请选择需要删除的学生!');
+          }
+          
+        }
+      },
+      initData() {}
+    },
+    created() {
+      this.initData();
+    },
+    computed: {
+    }
+  }
+</script>

+ 101 - 0
TEAMModelOS/ClientApp/view/student-account/IndexIview.less

@@ -0,0 +1,101 @@
+.sc-container .ivu-input, .ivu-select-selection {
+    background: none;
+    color: white;
+}
+.sc-menu .ivu-input, .ivu-select-selection {
+    border: 1px solid #424242;
+}
+.sc-container .ivu-input:focus, .ivu-input:hover {
+    border-color: #57A3F3 !important;
+}
+.sc-container .ivu-select-selection:focus, .ivu-select-selection:hover {
+    border-color: #57A3F3 !important;
+}
+
+.sc-content .ivu-table, td.ivu-table-column-center, th.ivu-table-column-center {
+    background: none;
+    color: #a5a5a5;
+    border-bottom: 1px solid #424242;
+}
+
+.sc-content .ivu-table-wrapper {
+    border: none;
+}
+
+.sc-content .ivu-table::before {
+    content: none;
+}
+
+.sc-content .ivu-table::after {
+    content: none;
+}
+
+.sc-content .ivu-table-row-hover {
+    /*background-color: #222222;*/
+    background: -webkit-linear-gradient(left, #282828, #363636); /* Safari 5.1 - 6.0 */
+    background: -o-linear-gradient(right, #282828, #363636); /* Opera 11.1 - 12.0 */
+    background: -moz-linear-gradient(right, #282828, #363636e); /* Firefox 3.6 - 15 */
+    background: linear-gradient(to right,#282828, #363636); /* 标准的语法 */
+}
+.sc-content .ivu-table-row-hover .item-tools{
+    display:inline-block !important;
+}
+
+.ivu-table-overflowY {
+    &::-webkit-scrollbar { /*滚动条整体样式*/
+        width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
+        height: 1px;
+    }
+
+    &::-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);
+    }
+}
+
+.sc-content .ivu-table-row-hover td {
+    background: none !important;
+}
+
+.sc-content .ivu-table-header {
+    background-color: #222222;
+}
+
+.sc-content .ivu-checkbox-inner {
+    background: none;
+    border: 1px solid #424242;
+}
+
+.sc-content .ivu-checkbox-checked .ivu-checkbox-inner:after {
+    border-color: #48D2B0;
+}
+
+.sc-content .ivu-checkbox-focus {
+    box-shadow: none;
+}
+
+th[rowspan="1"] {
+    display: none;
+}
+.item-tools .ivu-icon{
+    cursor:pointer;
+    &:first-child{
+        margin-right:20px;
+    }
+}
+.ivu-table-tip td{
+    background:#383838;
+}
+.sc-content .ivu-page li {
+    background: none;
+}
+.sc-menu-left .ivu-input-group {
+    float: left;
+    margin-top: 6px;
+    margin-left:18px;
+}

+ 26 - 0
TEAMModelOS/ClientApp/view/student-account/add-student/AddStudent.less

@@ -0,0 +1,26 @@
+.confirm-btn{
+    width:100%;
+    height:40px;
+    line-height:40px;
+    text-align:center;
+    background-color:#4f4f4f;
+    margin:auto;
+    color:#A1A1A1;
+    font-size:18px;
+    font-weight:600;
+    letter-spacing:2px;
+    cursor:pointer;
+    user-select:none;
+}
+.confirm-btn-active {
+    background-color: #6DE2C4;
+    color:white;
+}
+.account-form {
+    width:90%;
+    margin:auto;
+}
+.account-item {
+    color: white;
+    font-size: 16px;
+}

+ 332 - 0
TEAMModelOS/ClientApp/view/student-account/add-student/AddStudent.vue

@@ -0,0 +1,332 @@
+<style lang="less" scoped>
+  @import './AddStudent.less';
+</style>
+<style lang="less">
+  .add-student .ivu-modal-content{
+    background-color:#404040 !important;
+  }
+  .add-student .ivu-modal-header {
+    border:none;
+  }
+  .add-student .ivu-modal-footer {
+    border:none;
+  }
+  .add-student .ivu-modal-mask {
+    background-color:rgba(20,20,20,.7);
+  }
+  .add-student .ivu-input {
+    background:none;
+    border:none;
+    border-bottom:1px solid #828282;
+    border-radius:0px;
+    color:white;
+    font-size:16px;
+  }
+  .add-student .ivu-form-item-label {
+    color:#929292;
+  }
+  .add-student .ivu-form-item-required .ivu-form-item-label:before{
+    color:#6DE2C4;
+  }
+  .add-student .ivu-form-item-error .ivu-input:focus {
+    border:none;
+  }
+  .add-student .ivu-input-group-prepend{
+    border:none;
+    background:none;
+    color:white;
+    font-size:14px;
+  }
+  .add-student .ivu-checkbox-wrapper {
+    float:right;
+    color:#929292;
+  }
+  .add-student .ivu-checkbox-inner {
+    background:none;
+    border-color:#6DE2C4;
+  }
+  .add-student .ivu-checkbox-checked .ivu-checkbox-inner:after {
+    border-color:#6DE2C4;
+  }
+  .account-form .ivu-select-selection {
+    border-color: #828282;
+  }
+  .account-form .ivu-select-selection:hover {
+    border-color: #57a3f3;
+  }
+  .account-form .ivu-select-input {
+    color:white;
+    font-size:16px;
+  }
+  .add-student .ivu-modal-close .ivu-icon-ios-close:hover {
+    color:white !important;
+  }
+
+</style>
+<template>
+  <Modal v-model="show" width="520" class="add-student" :mask-closable="false" @on-cancel="cancel">
+    <div slot="header"></div>
+    <div class="account-form">
+      <!--新增学生表单-->
+      <Form ref="studentInfoForm" :model="studentInfo" label-position="top" :rules="ruleValidate" :show-message="showError" v-if="bizType == 1">
+        <FormItem label="账号资讯" prop="account">
+          <Input v-model="studentInfo.account" placeholder="请输入账号名称" @on-change="setPassword(same)">
+          <span slot="prepend">{{schoolCode}}#</span>
+          </Input>
+        </FormItem>
+        <FormItem label="密码" prop="password">
+          <Input v-model="studentInfo.password" placeholder="请输入账号密码"></Input>
+          <Checkbox v-model="same" @on-change="setPassword">与账号相同</Checkbox>
+        </FormItem>
+        <FormItem label="学生名称" prop="name">
+          <Input v-model="studentInfo.name" placeholder="请输入学生名称"></Input>
+        </FormItem>
+        <FormItem label="教室资讯(选填)" prop="classroom">
+          <Select filterable v-model="studentInfo.classroom" style="width:100%" placeholder="请选择教室">
+            <Option v-for="(item,index) in classroomList" :value="item.id" :key="item.id" @click.native="getCurrentClassroom(index)">{{ item.name }}</Option>
+          </Select>
+          <span style="float:right;color:#6DE2C4;cursor:pointer;text-decoration:underline;" @click="createClassroom">建立新教室</span>
+        </FormItem>
+        <FormItem label="学制资讯" prop="period">
+          <span style="color:white;margin-left:15px;">{{studentInfo.period == "" ? "— —" : studentInfo.period}}</span>
+        </FormItem>
+        <FormItem label="学级" prop="grade">
+          <span style="color:white;margin-left:15px;">{{studentInfo.grade == "" ? "— —" : studentInfo.grade}}</span>
+        </FormItem>
+      </Form>
+      <!--修改信息表单-->
+      <Form ref="updateForm" :model="editStudentInfo[0]" label-position="top" :rules="ruleValidate" :show-message="showError" v-if="bizType == 2">
+        <FormItem label="选取项目" v-if="editStudentInfo.length > 1">
+          <span class="account-item" v-for="(item,index) in editStudentInfo">{{item.account}}{{index < editStudentInfo.length - 1 ? ", ":""}}</span>
+        </FormItem>
+        <FormItem :label="'总计:'+editStudentInfo.length+' 条'" v-if="editStudentInfo.length > 1">
+        </FormItem>
+        <FormItem label="账号资讯" prop="account" v-if="editStudentInfo.length == 1">
+          <Input v-model="editStudentInfo[0].account" placeholder="请输入账号名称" @on-change="setPassword(same)">
+          <span slot="prepend">{{schoolCode}}#</span>
+          </Input>
+        </FormItem>
+        <FormItem label="密码" prop="password" v-if="editStudentInfo.length == 1">
+          <Input v-model="editStudentInfo[0].password" placeholder="请输入账号密码"></Input>
+          <Checkbox v-model="same" @on-change="setPassword">与账号相同</Checkbox>
+        </FormItem>
+        <FormItem label="学生名称" prop="name" v-if="editStudentInfo.length == 1">
+          <Input v-model="editStudentInfo[0].name" placeholder="请输入学生名称"></Input>
+        </FormItem>
+        <FormItem label="教室资讯(选填)" prop="classroom">
+          <Select filterable v-model="editStudentInfo[0].classroom" style="width:100%" placeholder="请选择教室">
+            <Option v-for="(item,index) in classroomList" :value="item.id" :key="item.id" @click.native="getCurrentClassroom(index)">{{ item.name }}</Option>
+          </Select>
+          <span style="float:right;color:#6DE2C4;cursor:pointer;text-decoration:underline;" @click="createClassroom">建立新教室</span>
+        </FormItem>
+        <FormItem label="学制资讯" prop="period">
+          <span style="color:white;margin-left:15px;">{{editStudentInfo[0].period == "" ? "— —" : editStudentInfo[0].period}}</span>
+        </FormItem>
+        <FormItem label="学级" prop="grade">
+          <span style="color:white;margin-left:15px;">{{editStudentInfo[0].grade == "" ? "— —" : editStudentInfo[0].grade}}</span>
+        </FormItem>
+      </Form>
+      <div class="confirm-btn" @click="confirm()" :class="isFull?'confirm-btn-active':''">
+        {{isFull?"保存":"建立账号"}}
+      </div>
+    </div>
+    <div slot="footer">
+
+    </div>
+  </Modal>
+</template>
+<script>
+  export default {
+    props: {
+      isShow: {
+        type: Boolean,
+        default: false
+      },
+      schoolCode: {
+        type: String,
+        default: ""
+      },
+      editStudentInfo: {
+        type: Array,
+        default: []
+      },
+      bizType: {
+        type: Number,
+        default:0
+      }
+    },
+    data() {
+      return {
+        showError: false,
+        isFull:false,
+        classroomList:[],
+        same:'',
+        list:[],
+        studentInfo: {
+          account: "",
+          password: "",
+          name:"",
+          classroom: "",
+          period: "",
+          grade:""
+        },
+        ruleValidate: {
+          account: [
+            { required: true, message: '账号不能为空', trigger: 'blur' }
+          ],
+          password: [
+            { required: true, message: '密码不能为空', trigger: 'blur' }
+          ],
+          classroom: [
+            { required: true, message: '教室资讯不能为空', trigger: 'blur' }
+          ],
+          name: [
+            { required: true, message: '教室资讯不能为空', trigger: 'blur' }
+          ],
+          period: [
+            { required: true, message: '学制不能为空', trigger: 'blur' }
+          ],
+          grade: [
+            { required: true, message: '学级不能为空', trigger: 'blur' }
+          ]
+        },
+        modal_loading: false
+      }
+    },
+    computed: {
+      show: {
+        get() {
+          if (this.bizType == 2 && this.isShow == true) {
+            if (this.editStudentInfo.length == 1) {
+              let arr = this.editStudentInfo[0].account.split("#");
+              if (arr.length > 1) {
+                this.editStudentInfo[0].account = arr[1];
+              }
+            }
+          }
+          return this.isShow;
+        },
+        set(value){
+        }
+      },
+    },
+    methods: {
+      cancel() {
+        this.same = false;
+        this.$emit("saveStudentInfo", {
+              action: 0
+            });
+      },
+      setPassword(data) {
+        if (this.bizType == 2) {
+          if (data) {
+            //this.editStudentInfo[0].password = this.editStudentInfo[0].account;
+            this.$set(this.editStudentInfo[0], 'password', this.editStudentInfo[0].account);
+          } else {
+            //this.editStudentInfo[0].password = "";
+            this.$set(this.editStudentInfo[0], 'password', "");
+          }
+        } else {
+          if (data) {
+            this.studentInfo.password = this.studentInfo.account;
+          } else {
+            this.studentInfo.password = "";
+          }
+        }
+      },
+      getCurrentClassroom(index) {
+        if (this.bizType == 1) {
+          this.studentInfo.period = this.classroomList[index].period;
+          this.studentInfo.grade = this.classroomList[index].grade;
+        } else {
+          for (let i = 0; i < this.editStudentInfo.length; i++) {
+            this.editStudentInfo[i].period = this.classroomList[index].period;
+            this.editStudentInfo[i].grade = this.classroomList[index].grade;
+          }
+        }
+        this.$forceUpdate();
+      },
+      getClassroom() {
+        this.$api.schoolSetting.findClassInfo({
+          SchoolCode: this.schoolCode
+        }).then(res => {
+          if (res.error == null) {
+            if (res.result.data.length > 0) {
+              this.classroomList = res.result.data;
+            }
+          }
+        });
+
+      },
+      confirm() {
+        this.showError = true;
+        console.log(this.editStudentInfo);
+        console.log(this.studentInfo);
+        if (this.isFull) {
+          this.same = false;
+          if (this.bizType == 2) {
+            this.$emit("saveStudentInfo", {
+              action: 2,//批量修改数据
+              studentInfo: this.editStudentInfo
+            });
+            this.$refs.updateForm.resetFields();
+          } else {
+            this.$emit("saveStudentInfo", {
+              action: 1,//修改一条数据
+              studentInfo: this.studentInfo
+            });
+            this.$refs.studentInfoForm.resetFields();
+          }
+          
+        } else {
+          this.$Message.error('请完善信息!');
+        }
+      },
+      createClassroom() {
+        this.$router.push({
+          path:"/school/classroom"
+        });
+      }
+    },
+    created(){
+      this.getClassroom();
+    },
+    mounted() {
+
+    },
+    watch: {
+      studentInfo: {
+        handler(newValue, oldValue) {
+          if (this.bizType == 1) {
+            this.showError = false;
+            this.$refs.studentInfoForm.validate((valid) => {
+              if (valid) {
+                this.isFull = true;
+              } else {
+                this.isFull = false;
+              }
+            });
+          }
+        },
+        deep: true
+      },
+      editStudentInfo: {
+        handler(newValue, oldValue) {
+          this.showError = false;
+          setTimeout(() => {
+            if (this.bizType == 2) {
+              this.$refs.updateForm.validate((valid) => {
+                if (valid) {
+                  this.isFull = true;
+                } else {
+                  this.isFull = false;
+                }
+              });
+            }
+          },1000);
+        },
+        deep: true
+      }
+    }
+  }
+</script>

+ 147 - 0
TEAMModelOS/ClientApp/view/student-account/add-student/Authorization.less

@@ -0,0 +1,147 @@
+@borderColor: #626262;
+.model-title{
+    color:#7F7F7F;
+    font-size:18px;
+    font-weight:800;
+    display:inline-block;
+    width:100%;
+    text-align:center;
+}
+.import-tips {
+    color: #707070;
+    font-size: 18px;
+    line-height: 30px;
+    font-weight: 600;
+}
+.my-btn {
+    width: 100%;
+    height: 40px;
+    line-height: 40px;
+    text-align: center;
+    background-color: #4f4f4f;
+    margin: auto;
+    color: #A1A1A1;
+    font-size: 18px;
+    font-weight: 600;
+    letter-spacing: 2px;
+    cursor: pointer;
+    margin-bottom:15px;
+}
+.my-btn-active {
+    background-color: #6DE2C4;
+    color: white;
+}
+.drawer-footer{
+    position:absolute;
+    left:20px;
+    bottom:40px;
+    width:380px;
+}
+.auth-info {
+    width: 100%;
+    border-bottom: 1px solid @borderColor;
+    padding-bottom: 30px;
+    margin-bottom:25px;
+    &-title {
+        color: white;
+        font-size: 18px;
+    }
+
+    &-discreption {
+        color: #8E8E8E;
+        margin-top: 5px;
+        margin-bottom: 25px;
+    }
+
+    &-count-item {
+        width: 100%;
+        margin-top: 5px;
+        color: #8E8E8E;
+        font-size:14px;
+        font-weight:600;
+        & span{
+            display:inline-block;
+        }
+    }
+    &-label{
+        width:60%;
+    }
+    &-num{
+        color:#DDDDDD;
+    }
+}
+.auth-rule {
+    margin-top:15px;
+    &-item {
+        margin-top: 25px;
+        width: 100%;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        justify-content: space-between;
+    }
+
+    &-label {
+        color: #aaaaaa;
+        font-size: 14px;
+    }
+
+    &-btn {
+        padding: 2px 12px; 
+        background: #808080;
+        margin-right: 50px;
+        color: #DDDDDD; 
+        border-radius: 5px;
+        width: -webkit-fit-content;
+        width: -moz-fit-content;
+        width: -o-fit-content;
+        width: fit-content;
+        cursor:pointer;
+        user-select:none;
+        &-active{
+            background-color:#6de2c4;
+        }
+    }
+}
+.collapse-header {
+    &-box {
+        width: 100%;
+        display:inline-block;
+    }
+
+    &-label {
+        padding-left: 10px;
+        height: 18px;
+        line-height:18px;
+        font-size: 15px;
+        font-weight: 600;
+        color: #9E9E9E;
+        width: 60%;
+        box-sizing:border-box;
+        display: inline-block;
+    }
+
+    &-num {
+        padding-left: 10px;
+        height: 18px;
+        font-size: 15px;
+        font-weight: 600;
+        color: #9F9F9F;
+    }
+}
+.auth-num-item ul {
+    list-style: none;
+    color: #9F9F9F;
+    font-size: 14px;
+    width: 100%;
+
+    & li {
+        margin-top: 5px;
+        width: 100%;
+    }
+
+    & li span:nth-child(1) {
+        display: inline-block;
+        width: 63%;
+    }
+}

+ 263 - 0
TEAMModelOS/ClientApp/view/student-account/add-student/Authorization.vue

@@ -0,0 +1,263 @@
+<style lang="less" scoped>
+  @import './Authorization.less';
+</style>
+<style lang="less">
+  .auth-box .ivu-drawer-content {
+    border-left:1px solid #383838;
+    background-color:#404040;
+  }
+  .auth-box .ivu-drawer-header {
+    border-color:#424242;
+  }
+  .auth-box .ivu-drawer-body {
+    box-sizing:content-box;
+  }
+  .auth-rule .ivu-select-selection {
+    border-color:#AAAAAA;
+    margin:0px 5px;
+  }
+  .auth-rule .ivu-input {
+    border-color: #AAAAAA;
+    text-align:center;
+  }
+  .auth-rule .ivu-collapse,.ivu-collapse-content {
+    background:none;
+    border:none;
+  }
+  .auth-rule .ivu-collapse>.ivu-collapse-item>.ivu-collapse-header {
+    border:none;
+    padding-left:2px;
+  }
+    .auth-rule .ivu-collapse > .ivu-collapse-item {
+      border:none;
+    }
+  .auth-rule .ivu-icon-ios-arrow-forward:before {
+    content:"";
+  }
+  .auth-rule .ivu-collapse-item-active .collapse-header-label {
+    border-left:3px solid white;
+  }
+  .auth-rule .ivu-collapse > .ivu-collapse-item > .ivu-collapse-header > i {
+    display:none;
+  }
+  .auth-rule .ivu-collapse-item-active .ivu-collapse-content-box {
+    border-bottom:1px solid #AAAAAA;
+  }
+</style>
+<template>
+    <Drawer title="服务授权管理"
+            v-model="show"
+            width="420"
+            :transfer="!flag"
+            @on-close="close"
+            inner
+            class-name="sc-content" class="auth-box">
+      <p slot="header" style="color:#a5a5a5;">服务授权管理</p>
+      <div class="auth-info">
+        <h3 class="auth-info-title">
+          AClassOne智慧学伴服务授权
+        </h3>
+        <p class="auth-info-discreption">赋予持有该服务授权的学生TEAM MODEL ID使用智慧学伴App权限。</p>
+        <div class="auth-info-count-item">
+          <span class="auth-info-label">学校总授权数</span>
+          <span class="auth-info-num">356</span>
+        </div>
+        <div class="auth-info-count-item">
+          <span class="auth-info-label">今日已取用授权数</span>
+          <span class="auth-info-num">287</span>
+        </div>
+        <div class="auth-info-count-item">
+          <span class="auth-info-label">可使用授权数</span>
+          <span class="auth-info-num">69</span>
+        </div>
+      </div>
+      <div class="auth-rule">
+        <p class="auth-info-discreption">各学制授权使用状态</p>
+        <!--<div class="auth-rule-item">
+          <div class="auth-rule-label">套用至所有当前节选项目</div>
+          <div class="auth-rule-btn">套用</div>
+        </div>
+        <div class="auth-rule-item">
+          <div class="auth-rule-label">
+            <span>套用至所有当前节选目标</span>
+            <Input size="small" placeholder="—" style="width: 50px;border-color:#AAAAAA;" />
+            <span>至</span>
+            <Input size="small" placeholder="—" style="width: 50px" />
+            <span>项</span>
+          </div>
+          <div class="auth-rule-btn">套用</div>
+        </div>
+        <div class="auth-rule-item">
+          <div class="auth-rule-label">
+            <span>套用至</span>
+            <Select size="small" v-model="list" style="width:140px" placeholder="请选择学制">
+              <Option v-for="item in list" :value="item.value" :key="item.value">{{ item.label }}</Option>
+            </Select>
+            <span>所有项目</span>
+          </div>
+          <div class="auth-rule-btn">套用</div>
+        </div>
+        <div class="auth-rule-item">
+          <div class="auth-rule-label">
+            <span>套用至</span>
+            <Select size="small" v-model="list" style="width:140px" placeholder="请选择学级">
+              <Option v-for="item in list" :value="item.value" :key="item.value">{{ item.label }}</Option>
+            </Select>
+            <span>所有项目</span>
+          </div>
+          <div class="auth-rule-btn">套用</div>
+        </div>
+        <div class="auth-rule-item">
+          <div class="auth-rule-label">
+            <span>套用至</span>
+            <Select size="small" v-model="list" style="width:140px" placeholder="请选择班级">
+              <Option v-for="item in list" :value="item.value" :key="item.value">{{ item.label }}</Option>
+            </Select>
+            <span>所有项目</span>
+          </div>
+          <div class="auth-rule-btn">套用</div>
+        </div>
+        <div class="auth-rule-item">
+          <div class="auth-rule-label">套用至全校所有项目</div>
+          <div class="auth-rule-btn">套用</div>
+        </div>-->
+        <Collapse  accordion>
+          <Panel name="1">
+            <div class="collapse-header-box">
+              <span class="collapse-header-label">小学使用数</span><span class="collapse-header-num">188</span>
+            </div>
+            <div slot="content" class="auth-num-item">
+              <ul>
+                <li>
+                  <span>一年级使用数</span>
+                  <span>58</span>
+                </li>
+                <li>
+                  <span>二年级使用数</span>
+                  <span>46</span>
+                </li>
+                <li>
+                  <span>三年级使用数</span>
+                  <span>86</span>
+                </li>
+                <li>
+                  <span>四年级使用数</span>
+                  <span>35</span>
+                </li>
+                <li>
+                  <span>五年级使用数</span>
+                  <span>48</span>
+                </li>
+                <li>
+                  <span>六年级使用数</span>
+                  <span>78</span>
+                </li>
+              </ul>
+            </div>
+          </Panel>
+          <Panel name="2">
+            <div style="display:inline-block;" class="collapse-header-box">
+              <span class="collapse-header-label">初中使用数</span><span class="collapse-header-num">135</span>
+            </div>
+            <div slot="content" class="auth-num-item">
+              <ul>
+                <li>
+                  <span>一年级使用数</span>
+                  <span>58</span>
+                </li>
+                <li>
+                  <span>二年级使用数</span>
+                  <span>46</span>
+                </li>
+                <li>
+                  <span>三年级使用数</span>
+                  <span>86</span>
+                </li>
+              </ul>
+            </div>
+          </Panel>
+          <Panel name="3">
+            <div style="display:inline-block;" class="collapse-header-box">
+              <span class="collapse-header-label">高中使用数</span><span class="collapse-header-num">89</span>
+            </div>
+            <div slot="content" class="auth-num-item">
+              <ul>
+                <li>
+                  <span>一年级使用数</span>
+                  <span>58</span>
+                </li>
+                <li>
+                  <span>二年级使用数</span>
+                  <span>46</span>
+                </li>
+                <li>
+                  <span>三年级使用数</span>
+                  <span>86</span>
+                </li>
+              </ul>
+            </div>
+          </Panel>
+        </Collapse>
+      </div>
+      <!--<div class="drawer-footer">
+        <div class="my-btn" @click="confirm()">
+          收回所有授权
+        </div>
+        <div class="my-btn my-btn-active" @click="confirm()" >
+          保存所有变更
+        </div>
+      </div>-->
+    </Drawer>
+</template>
+<script>
+  export default {
+    props: {
+      isShow: {
+        type: Boolean,
+        default: false
+      },
+      schoolCode: {
+        type: String,
+        default: ""
+      }
+    },
+    data() {
+      return {
+        flag: true,
+        list:[]
+      }
+    },
+    computed: {
+      show: {
+        get(){
+          return this.isShow;
+        },
+        set(value){
+        }
+      },
+      
+    },
+    watch: {
+    },
+    methods: {
+      close() {
+        this.$emit("closeAuth", {
+          action: 0
+        });
+      },
+      confirm() {
+        this.$emit("closeAuth", {
+          action: 1
+        });
+      }
+    },
+    created(){
+    },
+    mounted() {
+
+    },
+    watch: {
+      
+    }
+  }
+</script>

+ 137 - 0
TEAMModelOS/ClientApp/view/student-account/add-student/IImportStudent.less

@@ -0,0 +1,137 @@
+.import-student .ivu-modal-content {
+    background-color: #383838 !important;
+}
+
+.import-student .ivu-modal-header {
+    border-color: #454545;
+    background-color: #383838;
+}
+
+.import-student .ivu-modal-footer {
+    border: none;
+}
+
+.import-student .content {
+    text-align: center;
+}
+
+.import-student .ivu-modal-content {
+    height: 750px;
+}
+
+.import-student .ivu-modal-mask {
+    background-color: rgba(20,20,20,.7);
+}
+
+.import-student .ivu-upload-list-file {
+    display: none;
+}
+
+.import-student .ivu-table, td.ivu-table-column-center, th.ivu-table-column-center {
+    background: none;
+    color: #a5a5a5;
+    border-bottom: 1px solid #424242;
+}
+.ivu-table .account-error-row-bg {
+    background: -webkit-linear-gradient(left, #383838, #442F2E); /* Safari 5.1 - 6.0 */
+    background: -o-linear-gradient(right, #383838, #442F2E); /* Opera 11.1 - 12.0 */
+    background: -moz-linear-gradient(right, #383838, #442F2E); /* Firefox 3.6 - 15 */
+    background: linear-gradient(to right,#383838, #442F2E); /* 标准的语法 */
+}
+.ivu-table .account-warning-row-bg {
+    background: -webkit-linear-gradient(left, #383838, #413A28); /* Safari 5.1 - 6.0 */
+    background: -o-linear-gradient(right, #383838, #413A28); /* Opera 11.1 - 12.0 */
+    background: -moz-linear-gradient(right, #383838, #413A28); /* Firefox 3.6 - 15 */
+    background: linear-gradient(to right,#383838, #413A28); /* 标准的语法 */
+}
+
+.import-student .ivu-table-wrapper {
+    border: none;
+}
+
+.import-student .ivu-table::before {
+    content: none;
+}
+
+.import-student .ivu-table::after {
+    content: none;
+}
+
+.import-student .ivu-table-row-hover {
+    background: -webkit-linear-gradient(right, #282828, #363636); /* Safari 5.1 - 6.0 */
+    background: -o-linear-gradient(left, #282828, #363636); /* Opera 11.1 - 12.0 */
+    background: -moz-linear-gradient(left, #282828, #363636e); /* Firefox 3.6 - 15 */
+    background: linear-gradient(to left,#282828, #363636); /* 标准的语法 */
+}
+
+.import-student .ivu-table-overflowX {
+    &::-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);
+    }
+}
+.import-student .ivu-table-wrapper{
+    &::-webkit-scrollbar { /*滚动条整体样式*/
+        width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
+        height: 1px;
+    }
+
+    &::-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);
+    }
+}
+.import-student .ivu-table-row-hover td {
+    background: none !important;
+}
+
+.import-student .ivu-table-header {
+    background-color: #222222;
+}
+
+.import-student .ivu-table td {
+    background: none;
+    color: #a5a5a5;
+    border-bottom: 1px solid #424242;
+}
+.import-student .ivu-table th {
+    background: none;
+    color: #a5a5a5;
+    border-bottom: 1px solid #424242;
+}
+.import-student .ivu-checkbox-inner {
+    background: none;
+    border: 1px solid #666666;
+}
+
+.import-student .ivu-checkbox-checked .ivu-checkbox-inner:after {
+    border-color: #48D2B0;
+}
+
+.import-student .ivu-checkbox-focus {
+    box-shadow: none;
+}
+
+.import-student .ivu-spin-fix {
+    background-color: rgba(200,200,200,.2);
+    border:none;
+}
+.form-body .ivu-btn {
+    border: none;
+    padding: 0px;
+}

+ 123 - 0
TEAMModelOS/ClientApp/view/student-account/add-student/ImportExcel.vue

@@ -0,0 +1,123 @@
+<template>
+    <div class="form-body">
+        <Row>
+            <div class="ivu-upload-list-file" v-if="file !== null">
+                <Icon type="ios-stats"></Icon>
+                {{ file.name }}
+                <Icon v-show="showRemoveFile" type="ios-close" class="ivu-upload-list-remove" @click.native="handleRemove()"></Icon>
+            </div>
+        </Row>
+        <Row>
+            <transition name="fade">
+                <Progress v-if="showProgress" :percent="progressPercent" :stroke-width="2">
+                    <div v-if="progressPercent == 100">
+                        <Icon type="ios-checkmark-circle"></Icon>
+                        <span>成功</span>
+                    </div>
+                </Progress>
+            </transition>
+        </Row>
+        <Row>
+            <Table :columns="tableTitle" :data="tableData" :loading="tableLoading" style="max-height:590px; overflow-y:scroll;"></Table>
+            <div style="background-color:white; width:100%; height:50px;">
+                <Upload action="" :before-upload="handleBeforeUpload" accept=".xls, .xlsx" style="display:block; float:right;">
+                    <Button :loading="uploadLoading" @click="openUploadFile" icon="ios-folder-open" class="btn">
+                        打开文件
+                    </Button>
+                    <Button :loading="uploadLoading" @click.stop="sendUploadFile" icon="md-cloud-upload" class="btn">
+                        上传文件
+                    </Button>
+                </Upload>
+            </div>
+        </Row>
+    </div>
+</template>
+<script>
+  import excel from '../../../utils/excel'
+    export default {
+        data() {
+            return {
+                uploadLoading: false,
+                progressPercent: 0,
+                showProgress: false,
+                showRemoveFile: false,
+                file: null,
+                tableData: [],
+                tableTitle: [],
+                tableLoading: false
+            }
+        },
+        methods: {
+            initUpload() {
+                this.file = null
+                this.showProgress = false
+                this.loadingProgress = 0
+                this.tableData = []
+                this.tableTitle = []
+            },
+            openUploadFile() {
+                this.initUpload()
+            },
+            handleRemove() {
+                this.initUpload()
+                this.$Message.info('打开的文件已删除!')
+            },
+            handleBeforeUpload(file) {
+                const fileExt = file.name.split('.').pop().toLocaleLowerCase()
+                if (fileExt === 'xlsx' || fileExt === 'xls') {
+                    this.readFile(file)
+                    this.file = file
+                } else {
+                    this.$Notice.warning({
+                        title: '文件类型错误',
+                        desc: '文件:' + file.name + '不是EXCEL文件,请选择后缀为.xlsx或者.xls的EXCEL文件。'
+                    })
+                }
+                return false
+            },
+            // 读取文件
+            readFile(file) {
+                const reader = new FileReader();
+                reader.readAsArrayBuffer(file);
+                reader.onloadstart = e => {
+                    this.uploadLoading = true
+                    this.tableLoading = true
+                    this.showProgress = true
+                }
+                reader.onprogress = e => {
+                    this.progressPercent = Math.round(e.loaded / e.total * 100)
+                }
+                reader.onerror = e => {
+                    this.$Message.error('文件读取出错')
+                }
+                reader.onload = e => {
+                    this.$Message.info('文件读取成功');
+                    const data = e.target.result;
+                    const { header, results } = excel.read(data, 'array');
+                    const tableTitle = header.map(item => { return { title: item, key: item } });
+                    this.tableData = results;
+                    this.tableTitle = tableTitle;
+                    this.uploadLoading = false;
+                    this.tableLoading = false;
+                    this.showRemoveFile = true;
+                    console.log(this.tableData);
+                }
+            },
+            sendUploadFile() {
+            }
+        },
+        mounted() {
+        }
+    }
+</script>
+<style scoped>
+    .btn {
+        background: white;
+        margin-top: 15px;
+        font-size: 15px;
+        padding: 5px 10px;
+        width: 120px;
+        padding: 4px 10px;
+        margin-left: 10px;
+    }
+</style>

+ 95 - 0
TEAMModelOS/ClientApp/view/student-account/add-student/ImportStudent.less

@@ -0,0 +1,95 @@
+.model-title{
+    color:#7F7F7F;
+    font-size:18px;
+    font-weight:800;
+    display:inline-block;
+    width:100%;
+    text-align:center;
+}
+.import-tips {
+    color: #707070;
+    font-size: 18px;
+    line-height: 30px;
+    font-weight: 600;
+}
+.btn {
+    background: white;
+    margin-top: 15px;
+    font-size: 15px;
+    padding: 5px 10px;
+    width: 120px;
+    padding: 4px 10px;
+    margin-left: 10px;
+}
+.table-info {
+    width: 100%;
+    padding-left: 35px;
+    text-align: left;
+    font-weight: 400;
+    font-size: 14px;
+
+    &-item {
+        display: inline-block;
+        margin-right: 50px;
+    }
+
+    & > &-item:nth-child(1) {
+        color: white;
+    }
+
+    & > &-item:nth-child(2) {
+        color: #1CCC9E;
+    }
+
+    & > &-item:nth-child(3) {
+        color: #E1B551;
+    }
+
+    & > &-item:nth-child(4) {
+        color: #ed6565;
+    }
+
+    & > &-item:nth-child(5) {
+        color: #11fd03;
+    }
+
+    /*& > &-item:last-child {
+        color: #ed6565;
+        float: right;
+        margin-right: 0px;
+        cursor: pointer;
+    }*/
+}
+.confirm-btn {
+    width: 36%;
+    min-width:200px;
+    height: 40px;
+    line-height: 40px;
+    text-align: center;
+    background-color: #4f4f4f;
+    margin: auto;
+    color: #A1A1A1;
+    font-size: 18px;
+    font-weight: 600;
+    letter-spacing: 2px;
+    cursor: pointer;
+    user-select: none;
+    margin-top: 10px;
+}
+
+.confirm-btn-active {
+    background-color: #6DE2C4;
+    color: white;
+}
+
+.account-error-tips {
+    color: #ed6565;
+}
+
+.account-success-tips {
+    color: #6DE2C4;
+}
+.account-warning-tips {
+    color: #E1B551;
+}
+

+ 339 - 0
TEAMModelOS/ClientApp/view/student-account/add-student/ImportStudent.vue

@@ -0,0 +1,339 @@
+<style lang="less" scoped>
+  @import './ImportStudent.less';
+</style>
+<style lang="less">
+  @import './IImportStudent.less';
+</style>
+<template>
+  <Modal v-model="show" width="70%" class="import-student" :mask-closable="false" @on-cancel="cancel">
+    <div slot="header">
+      <span class="model-title">导入学生名单</span>
+    </div>
+    <div class="content">
+      <div v-if="file == null">
+        <Upload action="" :before-upload="handleBeforeUpload" accept=".xls, .xlsx" :show-upload-list="false">
+          <Icon type="ios-folder" color="#606060" size="200" style="margin-top:60px;cursor:pointer;" @click="openUploadFile" />
+        </Upload>
+        <p class="import-tips" style="margin-top:40px;">拖拽欲汇入的学生账号和表格档案至此</p>
+        <p class="import-tips">或</p>
+        <p class="import-tips">点击文件图示打开文件浏览上传</p>
+      </div>
+      <div class="form-body" style="background:none;" v-if="file !== null">
+        <div class="ivu-upload-list-file">
+          <Icon type="ios-stats"></Icon>
+          {{ file.name }}
+          <Icon v-show="showRemoveFile" type="ios-close" class="ivu-upload-list-remove" @click.native="handleRemove()"></Icon>
+        </div>
+        <div class="table-info">
+          <div class="table-info-item">
+            <span class="table-info-label">总名单数:</span>
+            <span class="table-info-num">{{totalNum}}</span>
+          </div>
+          <div class="table-info-item">
+            <span class="table-info-label">已过滤重复账号:</span>
+            <span class="table-info-num">{{repeatNum}}</span>
+          </div>
+          <div class="table-info-item">
+            <span class="table-info-label">系统已存在账号:</span>
+            <span class="table-info-num">{{existNum}}</span>
+          </div>
+          <div class="table-info-item">
+            <span class="table-info-label">没有对应教室:</span>
+            <span class="table-info-num">{{noClassroomNum}}</span>
+          </div>
+
+          <div class="table-info-item">
+            <span class="table-info-label">可汇入:</span>
+            <span class="table-info-num">{{totalNum - repeatNum - existNum}}</span>
+          </div>
+          <!--<div class="table-info-item">
+            <Icon type="md-trash" size="18" color="white" @click="initUpload" />
+          </div>-->
+        </div>
+        <Table :row-class-name="rowClassName" :columns="tableTitle" :data="tableData" :loading="tableLoading" height="560" style="margin-top:15px; " @on-select="getSelectInfo" @on-select-cancel="getSelectInfo" @on-select-all="getSelectInfo" @on-select-all-cancel="cancelAll">
+          <template slot-scope="{ row,index }" slot="password">
+            <p>{{(row.password == '' || row.password == null)? '— —' : row.password+''}}</p>
+          </template>
+          <template slot-scope="{ row,index }" slot="status">
+            <p :class="(repeatAccounts.length == 0 || repeatAccounts.indexOf(row.account) == -1) ? 'account-success-tips':'account-error-tips'">{{(repeatAccounts.length == 0 || repeatAccounts.indexOf(row.account) == -1)?"":"警告:账号重复!" }}</p>
+            <p :class="(row.classroomCode == '' || row.classroomCode == null) ? 'account-warning-tips':''">{{(row.classroomCode == '' || row.classroomCode == null)?"注意:未找到指定教室":"" }}</p>
+          </template>
+        </Table>
+        <p style="margin-top:15px;">*未找到密码的项目将默认密码与账号相同</p>
+        <Button  class="confirm-btn confirm-btn-active" :loading="uploadLoading" @click="saveFileData">
+          建立账号
+        </Button>
+      </div>
+    </div>
+    <div slot="footer">
+
+    </div>
+  </Modal>
+</template>
+<script>
+  import ImportExcel from "./ImportExcel.vue"
+  import excel from '../../../utils/excel'
+  export default {
+    props: {
+      isShow: {
+        type: Boolean,
+        default: false
+      },
+      schoolCode: {
+        type: String,
+        default: ""
+      }
+    },
+    data() {
+      return {
+        totalNum:0,
+        repeatNum: 0,
+        existNum:0,
+        repeatAccounts:[],
+        noClassroomNum:0,
+        uploadLoading: false,
+        progressPercent: 0,
+        showProgress: false,
+        showRemoveFile: false,
+        selectionData:[],
+        file: null,
+        tableData: [],
+        tableTitle: [
+          {
+            type: 'selection',
+            width: 80,
+            align: 'center'
+          },
+          {
+            title: '账号资讯',
+            key:'account'
+          },
+          {
+            title: '密码',
+            slot:'password'
+          },
+          {
+            title: '姓名',
+            key:'name'
+          },
+          {
+            title: '教室名称',
+            key:'classroom'
+          },
+          {
+            title: '教室编码',
+            key:'classroomCode'
+          },
+          {
+            title: '异常状态',
+            slot:'status'
+          }
+        ],
+        tableLoading: false,
+        systemColumn: [
+          'account',
+          'password',
+          'name',
+          'classroom',
+          'classroomCode'
+        ]
+      }
+    },
+    components: {
+      ImportExcel
+    },
+    computed: {
+      show: {
+        get() {
+          return this.isShow;
+        },
+        set(value) {
+        }
+      },
+
+    },
+    watch: {
+    },
+    methods: {
+      rowClassName(row, index) {
+        let className = ''
+        if (!(this.repeatAccounts.length == 0 || this.repeatAccounts.indexOf(row.account) == -1)) {
+          className = className + 'account-error-row-bg ';
+        }
+        if (row.classroomCode == '' || row.classroomCode == null) {
+          className = className + 'account-warning-row-bg';
+        }
+        return className;
+      },
+      cancelUploadFile() {
+        this.file = null;
+      },
+      initUpload() {
+        this.file = null;
+        this.showProgress = false;
+        this.loadingProgress = 0;
+        this.tableData = [];
+      },
+      openUploadFile() {
+        this.initUpload()
+      },
+      handleRemove() {
+        this.initUpload()
+        this.$Message.info('打开的文件已删除!')
+      },
+      handleBeforeUpload(file) {
+        const fileExt = file.name.split('.').pop().toLocaleLowerCase()
+        if (fileExt === 'xlsx' || fileExt === 'xls') {
+          this.readFile(file)
+          this.file = file
+        } else {
+          this.$Notice.warning({
+            title: '文件类型错误',
+            desc: '文件:' + file.name + '不是EXCEL文件,请选择后缀为.xlsx或者.xls的EXCEL文件。'
+          })
+        }
+        return false
+      },
+      // 读取文件
+      readFile(file) {
+        this.tableLoading = true
+        const reader = new FileReader();
+        reader.readAsArrayBuffer(file);
+        reader.onloadstart = e => {
+          this.showProgress = true
+        }
+        reader.onprogress = e => {
+          this.progressPercent = Math.round(e.loaded / e.total * 100)
+        }
+        reader.onerror = e => {
+          this.$Message.error('文件读取出错')
+        }
+        reader.onload = e => {
+          const data = e.target.result;
+          const { header, results } = excel.read(data, 'array');
+          const tableColumn = header.map(item => { return { title: item, key: item } });
+          const columns = tableColumn.map(item => {
+            return item.key
+          });
+          const columnStr = columns.join("");
+          console.log(columnStr);
+          let flag = true;
+          let column = '';
+          for (let item of this.systemColumn) {
+            console.log(item);
+            let f = 0;
+            for (let i of columns) {
+              if (i == item) {
+                f = 1;
+                
+                break;
+              }
+            }
+            if (f == 0) {
+              column = item;
+              flag = false;
+              break;
+            }
+            //if (columnStr.indexOf(item) == -1) {
+            //  flag = false;
+              
+            //  break;
+            //}
+          }
+          if (flag) {
+            //处理表格导入数据类型
+            console.log(results);
+            this.tableData = results.filter(item => {
+              let arr = item.account.split("#");
+              if (arr.length == 2) {
+                for (let i of this.systemColumn) {
+                  if (typeof item[i] == "number") {
+                    item[i] = item[i] + "";
+                  }
+                  if (item.password == undefined) {
+                    item.password = arr[1]
+                  }
+                }
+                
+              } else {
+                item._disabled = true;
+              }
+              return item;
+            });
+            console.log(this.tableData);
+            //计算重复账号数量和重复账号,过滤重复账号
+            this.totalNum = this.tableData.length;
+            let accounts = this.tableData.map(item => { return item.account });
+            this.repeatAccounts = accounts.filter((item, index, self) => self.indexOf(item) != index);
+            this.repeatAccounts = this.repeatAccounts.filter((item, index, self) => self.indexOf(item) === index);
+            this.tableData = this.tableData.filter((item, index, self) => {
+              if (accounts.indexOf(item.account) === index) {
+                return 1;
+              } else {
+                return 0;
+              }
+            });
+
+            console.log(this.tableData);
+            accounts = accounts.filter((item, index, self) => self.indexOf(item) === index);
+            this.repeatNum = this.totalNum - accounts.length;
+            
+
+            //筛选没有教室账号
+            let noRoom = this.tableData.filter(item => { return (item.classroomCode == '' || item.classroomCode == null) });
+            this.noClassroomNum = noRoom.length;
+            this.$Message.info('文件读取成功!');
+            this.tableLoading = false;
+          } else {
+            this.$Message.error({
+              content: '缺少' + column + '信息,请完善,再导入!',
+              duration:4
+            });
+            this.tableLoading = false;
+          }
+          this.showRemoveFile = true;
+        }
+      },
+      saveFileData() {
+        this.uploadLoading = true;
+        
+        if (this.repeatNum != 0) {
+          let accounts = this.tableData.map(item => { return item.account });
+          let repeat = accounts.filter((item, index, self) => self.indexOf(item) != index);
+          this.tableData = this.tableData.filter((item, index, self) => repeat.indexOf(item.account) === -1)
+        }
+        this.$emit("importStudentInfo", {
+          data: this.tableData
+        });
+        this.uploadLoading = false;
+      },
+      cancel() {
+        this.initData();
+        this.$emit("importStudentInfo", {
+          data:[]
+        });
+      },
+      initData() {
+        this.totalNum = 0;
+        this.repeatNum = 0;
+        this.existNum = 0;
+        this.repeatAccounts = [];
+        this.noClassroomNum = 0;
+        this.uploadLoading =  false;
+        this.progressPercent = 0;
+        this.showProgress = false;
+        this.showRemoveFile =  false;
+        this.file = null;
+        this.tableData =  [];
+      }
+    },
+    created() {
+    },
+    mounted() {
+
+    },
+    watch: {
+
+    }
+  }
+</script>

+ 1 - 1
TEAMModelOS/package.json

@@ -24,12 +24,12 @@
     "core-js": "^2.6.9",
     "d3": "^5.9.2",
     "echarts": "^4.2.1",
-    "iview": "^3.4.2",
     "jwt-decode": "^2.2.0",
     "less": "^3.9.0",
     "mockjs": "^1.0.1-beta3",
     "videojs-contrib-hls": "^5.15.0",
     "videojs-contrib-hls.js": "^3.2.0",
+    "view-design": "^4.0.1",
     "vue": "^2.6.9",
     "vue-ckeditor5": "^0.4.1",
     "vue-count-to": "^1.0.13",