Bläddra i källkod

Merge branch 'develop' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop

CrazyIter 5 år sedan
förälder
incheckning
a6b5f8625f
26 ändrade filer med 650 tillägg och 147 borttagningar
  1. 24 0
      TEAMModelOS.Model/BaseInfo/Models/StuInfo.cs
  2. 12 0
      TEAMModelOS.Model/Evaluation/Models/CosmosModels/ClassIndex.cs
  3. 25 0
      TEAMModelOS.Model/Evaluation/Models/CosmosModels/SimpleExam.cs
  4. 14 1
      TEAMModelOS.Service/Evaluation/Implements/ExamInfoService.cs
  5. 3 0
      TEAMModelOS.Service/Evaluation/Interfaces/IExamInfoService.cs
  6. 5 3
      TEAMModelOS/ClientApp/common/BaseExamList.vue
  7. 15 12
      TEAMModelOS/ClientApp/locale/lang/en-US/stuAccount.js
  8. 18 2
      TEAMModelOS/ClientApp/locale/lang/en-US/totalAnalysis.js
  9. 11 6
      TEAMModelOS/ClientApp/locale/lang/zh-CN/stuAccount.js
  10. 19 1
      TEAMModelOS/ClientApp/locale/lang/zh-CN/totalAnalysis.js
  11. 6 3
      TEAMModelOS/ClientApp/locale/lang/zh-TW/stuAccount.js
  12. 18 2
      TEAMModelOS/ClientApp/locale/lang/zh-TW/totalAnalysis.js
  13. 1 1
      TEAMModelOS/ClientApp/view/school-mgmt/ClassroomSetting/ClassroomSetting.vue
  14. 1 1
      TEAMModelOS/ClientApp/view/school-mgmt/SystemSetting/SystemSetting.vue
  15. 63 11
      TEAMModelOS/ClientApp/view/student-account/Index.vue
  16. 19 7
      TEAMModelOS/ClientApp/view/student-account/add-student/AddStudent.vue
  17. 7 4
      TEAMModelOS/ClientApp/view/student-account/add-student/ImportStudent.less
  18. 126 44
      TEAMModelOS/ClientApp/view/student-account/add-student/ImportStudent.vue
  19. 1 1
      TEAMModelOS/ClientApp/view/student-analysis/total-analysis/TestAnalysis/QuestionList.css
  20. 13 13
      TEAMModelOS/ClientApp/view/student-analysis/total-analysis/TestAnalysis/QuestionList.vue
  21. 19 11
      TEAMModelOS/ClientApp/view/student-analysis/total-analysis/TestAnalysis/TestAnalysis.css
  22. 6 5
      TEAMModelOS/ClientApp/view/student-analysis/total-analysis/TestAnalysis/TestAnalysis.vue
  23. 21 0
      TEAMModelOS/ClientApp/view/student-analysis/total-analysis/index.css
  24. 22 11
      TEAMModelOS/ClientApp/view/student-analysis/total-analysis/index.vue
  25. 180 7
      TEAMModelOS/Controllers/Analysis/ChangeController.cs
  26. 1 1
      TEAMModelOS/JsonFile/IES/adas.json

+ 24 - 0
TEAMModelOS.Model/BaseInfo/Models/StuInfo.cs

@@ -0,0 +1,24 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Azure;
+
+namespace TEAMModelOS.Model.Evaluation.Models.CosmosModels
+{
+    public class StuInfo
+    {
+        [JsonProperty(PropertyName = "id")]
+        public string Id { get; set; }
+        public string StudentId { get; set; }
+        public string PassWord { get; set; } = "123456";
+        public string Name { get; set; }
+        public string SeatNo { get; set; }
+        public string ClassroomCode { get; set; }
+        public string GradeCode { get; set; }
+        [PartitionKey]
+        public string SchoolCode { get; set; }
+
+
+    }
+}

+ 12 - 0
TEAMModelOS.Model/Evaluation/Models/CosmosModels/ClassIndex.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.Model.Evaluation.Models.CosmosModels
+{
+    public class ClassIndex
+    {
+        public string ClassCode { get; set; }
+        public int[] IndexRange { get; set; }
+    }
+}

+ 25 - 0
TEAMModelOS.Model/Evaluation/Models/CosmosModels/SimpleExam.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.Model.Evaluation.Models.CosmosModels
+{
+    public class SimpleExam
+    {
+        public SimpleExam()
+        {
+            Classes = new List<Dictionary<object, int[]>>();
+            Result = new List<List<int>>();
+            Ids = new List<string>();
+            Point = new List<int>();
+        }
+
+        public string Name { get; set; }
+        public string Time { get; set; }
+
+        public List<Dictionary<object, int[]>> Classes { get; set; }
+        public List<List<int>> Result { get; set; }
+        public List<string> Ids { get; set; }
+        public List<int> Point { get; set; }
+    }
+}

+ 14 - 1
TEAMModelOS.Service/Evaluation/Implements/ExamInfoService.cs

@@ -244,7 +244,20 @@ namespace TEAMModelOS.Service.EvaluaTion.Implements
             await _cosmosrepository.SaveAll(answers);
             return exercises;
         }
-        
+
+        public async Task<SimpleExam> SaveToCosmos(SimpleExam simple)
+        {
+            await _cosmosrepository.Save(simple);
+            return simple;
+            //throw new NotImplementedException();
+        }
+
+        public async Task<List<StuInfo>> SaveListToCosmos(List<StuInfo> stu)
+        {
+            await _cosmosrepository.SaveAll(stu);
+            return stu;
+            //throw new NotImplementedException();
+        }
     }
 
 }

+ 3 - 0
TEAMModelOS.Service/Evaluation/Interfaces/IExamInfoService.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Threading.Tasks;
 using TEAMModelOS.Model.Evaluation.Dtos.Own;
+using TEAMModelOS.Model.Evaluation.Models.CosmosModels;
 using TEAMModelOS.Model.EvaluaTion.Dtos;
 using TEAMModelOS.Model.EvaluaTion.Models;
 using TEAMModelOS.Service.Core.Interfaces;
@@ -18,5 +19,7 @@ namespace TEAMModelOS.Service.EvaluaTion.Interfaces
 
         Task<List<ExerciseInfo>> SaveToCosmosExamAsync(List<ExerciseInfo> items, List<MemberAnswer> answers);
         Task<List<ExerciseInfo>> SaveToCosmosExam(List<ExerciseInfo> items, List<MemberAnswer> answers);
+        Task<SimpleExam> SaveToCosmos(SimpleExam simple);
+        Task<List<StuInfo>> SaveListToCosmos(List<StuInfo> stu);
     }
 }

+ 5 - 3
TEAMModelOS/ClientApp/common/BaseExamList.vue

@@ -20,7 +20,7 @@
     </div>-->
     <div class="btn-more" @click="goEvaluationList">
       <span style="font-size:14px"><Icon type="md-list-box" color="#a2a2a2" size="20" style="margin-right:5px;margin-bottom:5px;" />{{$t('totalAnalysis.newest')}}</span>
-      <span style="margin-top:2px">{{$t('totalAnalysis.more')}}<Icon type="ios-arrow-dropright" /></span>
+      <span style="margin-top:2px">{{$t('totalAnalysis.more')}} <Icon type="ios-arrow-dropright" /></span>
     </div>
     <!-- 测验列表展示区域 -->
     <div class="ex-list-wrap scrollstyle">
@@ -163,11 +163,13 @@
     cursor:pointer;
     box-shadow: 0px 1px 3px 0px #5a5a5a;
   }
+
   .ex-list-container .btn-more .ivu-icon {
     font-size:16px;
     margin-left:2px;
-    margin-bottom:2px;
-  }
+    margin-bottom:4px;
+    vertical-align:middle;
+    }
 
 
   /*滚动条样式重写*/

+ 15 - 12
TEAMModelOS/ClientApp/locale/lang/en-US/stuAccount.js

@@ -1,14 +1,15 @@
 export default {
   //table title
-  account: "account information",
-  stuName: "name",
-  classroomCode: "classroom code",
-  classroomName: "classroom name",
-  period: "school section (Campus)",
-  grade: "grade",
-  authStatus: "authorization status",
-  password: "password",
-  abnormalStatus: "abnormal state",
+  seatNo: "Seat number",
+  account: "Account information",
+  stuName: "Name",
+  classroomCode: "Classroom code",
+  classroomName: "Classroom name",
+  period: "School section (Campus)",
+  grade: "Grade",
+  authStatus: "Authorization status",
+  password: "Password",
+  abnormalStatus: "Abnormal state",
 
   //Index.vue
   menuAuth: "Authorization management",
@@ -58,11 +59,13 @@ export default {
   Importtips9: "missing",
   importTips10: "information, please complete and import again! ",
   importTips11: "file read succeeded! ",
+  importTips12: "Please check whether the table data is correct!",
   importInfo1: "total singular:",
-  importInfo2: "filtered duplicate accounts:",
-  importInfo3: "an account already exists in the system:",
+  importInfo2: "duplicate account number:",
+  importInfo3: "duplicate seat number:",
   importInfo4: "no corresponding Classroom:",
-  importInfo5: "importable:",
+  importInfo5: "an account already exists in the system:",
+  importInfo6: "importable:",
   passwordTips: "the default password is the same as the account for the item where the password is not found",
   submitList: "set up account",
 

+ 18 - 2
TEAMModelOS/ClientApp/locale/lang/en-US/totalAnalysis.js

@@ -25,7 +25,7 @@ export default {
 
   //ExamList.vue
   newest: "Newest Exams",
-  more: "more",
+  more: "View More ",
 
   //index.vue
   module1:"Score Analysis",
@@ -33,6 +33,7 @@ export default {
   module3:"Item Analysis",
   module4: "Knowledge Point Mastery",
   exportTable: "Export Table",
+  currentSubject:"Current Subject",
 
   //AchievementAnalysis.vue
   ach_title1: "Pass Rate Statistics",
@@ -171,7 +172,22 @@ export default {
   ka_table_text10: "RH Number of Wrong Questions",
   ka_table_text11: "RL Number of Wrong Questions",
 
-  ka_tip1: "* RH: High partition / RL:Low partition"
+  ka_tip1: "* RH: High partition / RL:Low partition",
+
+  //QuestionList.vue
+  ql_text1: "Total Score",
+  ql_text2: "Single Question",
+  ql_text3: "Multiple Question",
+  ql_text4: "Judgement Question",
+  ql_text5: "Complete Question",
+  ql_text6: "Subjective Question",
+  ql_text7: "Compose Question",
+  ql_text8: " points",
+  ql_text9: "View Answer and Explain",
+  ql_text10: "View Data Analysis",
+  ql_text11: "Answer",
+  ql_text12: "Explain",
+  ql_text13: "      Return",
 
 
 }

+ 11 - 6
TEAMModelOS/ClientApp/locale/lang/zh-CN/stuAccount.js

@@ -1,11 +1,12 @@
 export default {
   //table title
+  seatNo: "座号",
   account: "账号资讯",
   stuName: "姓名",
   classroomCode: "教室编码",
   classroomName: "教室名称",
   period: "学段(校区)",
-  grade: "级",
+  grade: "级",
   authStatus: "授权状态",
   password: "密码",
   abnormalStatus: "异常状态",
@@ -18,7 +19,7 @@ export default {
   delStu: "删除学生",
   searchHolder: "请输入关键字或账号资讯...",
   periodHolder: "所在学制",
-  gradeHolder: "所在级",
+  gradeHolder: "所在级",
   classroomHolder: "所在教室",
   tips1: "请选择需要修改的学生!",
   tips2Title: "删除学生",
@@ -34,11 +35,13 @@ export default {
   isSame: "与账号相同",
   stuName: "学生姓名",
   stuNameHolder: "请输入学生名称",
+  stuSeatNo: "座位号",
+  stuSeatNoHolder: "请设置座位号",
   classroomInfo: "教室信息",
   classroomInfoHolder: "请选择教室",
   newClassroom: "建立新教室",
   periodInfo: "学制信息",
-  gradeInfo: "级",
+  gradeInfo: "级",
   submitAccount: "建立账号",
   submitActive:"保存",
   chooseInfo: "选取项目",
@@ -58,11 +61,13 @@ export default {
   importTips9: "缺少",
   importTips10: "信息,请完善,再导入!",
   importTips11: "文件读取成功!",
+  importTips12: "请检查表格数据是否正确!",
   importInfo1:"总名单数:",
-  importInfo2:"已过滤重复账号:",
-  importInfo3:" 系统已存在账号:",
+  importInfo2:"账号重复:",
+  importInfo3:"座号重复:",
   importInfo4:"没有对应教室:",
-  importInfo5: " 可汇入:",
+  importInfo5:"系统已存在账号:",
+  importInfo6: "可汇入:",
   passwordTips: "*未找到密码的项目将默认密码与账号相同",
   submitList: "建立账号",
 

+ 19 - 1
TEAMModelOS/ClientApp/locale/lang/zh-CN/totalAnalysis.js

@@ -33,6 +33,7 @@ export default {
   module3: "试题分析",
   module4: "知识点掌握",
   exportTable: "导出表格",
+  currentSubject: "当前科目",
 
   //AchievementAnalysis.vue
   ach_title1: "及格率统计",
@@ -174,7 +175,24 @@ export default {
   ka_table_text10:"RH错题人数",
   ka_table_text11: "RL错题人数",
 
-  ka_tip1:"* RH:高分区段 / RL:低分区段"
+  ka_tip1: "* RH:高分区段 / RL:低分区段",
+
+
+  //QuestionList.vue
+  ql_text1:"试卷总分",
+  ql_text2:"单项选择题",
+  ql_text3:"多项选择器",
+  ql_text4:"判断题",
+  ql_text5:"填空题",
+  ql_text6:"问答题",
+  ql_text7: "综合题",
+  ql_text8: "分",
+  ql_text9: "查看答案与解析",
+  ql_text10: "查看数据分析",
+  ql_text11: "参考答案",
+  ql_text12: "答题解析",
+  ql_text13: "返回",
+
 
 
 }

+ 6 - 3
TEAMModelOS/ClientApp/locale/lang/zh-TW/stuAccount.js

@@ -1,5 +1,6 @@
 export default {
   //table title
+  seatNo: "座號",
   account: "帳號資訊",
   stuName: "姓名",
   classroomCode: "教室編碼",
@@ -58,11 +59,13 @@ export default {
   importTips9: "缺少",
   importTips10:"資訊,請完善,再導入!",
   importTips11:"檔案讀取成功!",
+  importTips12:"請檢查表格數據是否正確!",
   importInfo1:"總名單數:",
-  importInfo2:"已過濾重複帳號:",
-  importInfo3:"系統已存在帳號:",
+  importInfo2:"帳號重複:",
+  importInfo3:"座號重複:",
   importInfo4:"沒有對應教室:",
-  importInfo5:"可匯入:",
+  importInfo5:"系統已存在帳號:",
+  importInfo6:"可匯入:",
   passwordTips:"*未找到密碼的項目將默認密碼與帳號相同",
   submitList: "建立帳號",
 

+ 18 - 2
TEAMModelOS/ClientApp/locale/lang/zh-TW/totalAnalysis.js

@@ -32,7 +32,8 @@ export default {
   module2: "落点分析",
   module3: "試題分析",
   module4: "知識点掌握",
-  exportTable:"匯出表格",
+  exportTable: "匯出表格",
+  currentSubject: "當前科目",
 
   //AchievementAnalysis.vue
   ach_title1: "及格率統計",
@@ -171,7 +172,22 @@ export default {
   ka_table_text10: "RH錯題人數",
   ka_table_text11: "RL錯題人數",
 
-  ka_tip1: "* RH:高分區段 / RL:低分區段"
+  ka_tip1: "* RH:高分區段 / RL:低分區段",
+
+  //QuestionList.vue
+  ql_text1: "試卷總分",
+  ql_text2: "單項選擇題",
+  ql_text3: "多項選擇題",
+  ql_text4: "判斷題",
+  ql_text5: "填空題",
+  ql_text6: "問答題",
+  ql_text7: "綜合題",
+  ql_text8: "分",
+  ql_text9: "查看答案與解析",
+  ql_text10: "查看資料分析",
+  ql_text11: "參考答案",
+  ql_text12: "答題解析",
+  ql_text13: "返回",
 
 
 }

+ 1 - 1
TEAMModelOS/ClientApp/view/school-mgmt/ClassroomSetting/ClassroomSetting.vue

@@ -215,7 +215,7 @@
           user: "admin",
           teamModelId: "habook#0001",
           school: "醍摩豆书院",
-          schoolCode:"101010"
+          schoolCode:"HBCN"
         },
         hiTeachItem: {
           code: '',

+ 1 - 1
TEAMModelOS/ClientApp/view/school-mgmt/SystemSetting/SystemSetting.vue

@@ -173,7 +173,7 @@
           user: "admin",
           teamModelId: "habook#0001",
           school: "醍摩豆书院",
-          schoolCode:"101010"
+          schoolCode:"HBCN"
         },
         auto: true,
         updated:false,

+ 63 - 11
TEAMModelOS/ClientApp/view/student-account/Index.vue

@@ -9,17 +9,16 @@
   <div class="sc-container">
     <div class="sc-menu">
       <div class="sc-menu-left">
-        <Input v-model="serchText" clearable :placeholder="$t('stuAccount.searchHolder')" 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 v-model="searchText" clearable :placeholder="$t('stuAccount.searchHolder')" style="width: 28%;margin-left:20px;" :search="true"  @on-enter="searchData" @on-search="searchData" @on-clear="searchData">
         </Input>
-        <Select v-model="model" style="width:20%;margin-left:5%;" :placeholder="$t('stuAccount.periodHolder')" clearable>
-          <Option v-for="item in list" :value="item.value" :key="item.value">{{ item.label }}</Option>
+        <Select v-model="searchPeriod" style="width:20%;margin-left:5%;" :placeholder="$t('stuAccount.periodHolder')" clearable >
+          <Option v-for="(item,index) in schoolData.period" :value="item.code" :key="item.value" @click.native="getGradeList(index)">{{ item.name }}</Option>
         </Select>
-        <Select v-model="model" style="width:20%;margin-left:1%;" :placeholder="$t('stuAccount.gradeHolder')" clearable>
-          <Option v-for="item in list" :value="item.value" :key="item.value">{{ item.label }}</Option>
+        <Select v-model="searchGrade" style="width:20%;margin-left:1%;" :placeholder="$t('stuAccount.gradeHolder')" clearable>
+          <Option v-for="(item,index) in gradeList" :value="item.code" :key="item.code" @click.native="getClassroomList(index)">{{ item.name }}</Option>
         </Select>
-        <Select v-model="model" style="width:20%;margin-left:1%;" :placeholder="$t('stuAccount.classroomHolder')" clearable>
-          <Option v-for="item in list" :value="item.value" :key="item.value">{{ item.label }}</Option> 
+        <Select v-model="searchClassroom" ref="classroom" style="width:20%;margin-left:1%;" :placeholder="$t('stuAccount.classroomHolder')" clearable>
+          <Option v-for="(item,index) in classroomShowList" :value="item.classroomCode" :key="item.classroomCode" >{{ item.name }}</Option> 
         </Select>
       </div>
       <div class="sc-menu-right sc-text-no-select">
@@ -83,8 +82,15 @@
     },
     data() {
       return {
+        classroomList:[],
+        classroomShowList:[],
+        gradeList:[],
+        searchPeriod: "",
+        searchGrade: "",
+        searchClassroom:"",
+        schoolData: {},
         tableLoading: false,
-        serchText:'',
+        searchText:'',
         currentPage:1,
         pageSize:30,
         bizType:0,
@@ -98,7 +104,7 @@
           user: "admin",
           teamModelId: "habook#0001",
           school: "醍摩豆书院",
-          schoolCode:"101010"
+          schoolCode:"HBCN"
         },
         model: "",
         list: [],
@@ -109,6 +115,20 @@
       }
     },
     methods: {
+      getGradeList(index) {
+        this.gradeList = this.schoolData.period[index].grade;
+        this.classroomShowList = this.classroomList.filter((item) => { return item.period == this.schoolData.period[index].code });
+        if (this.classroomShowList.length == 0) {
+          this.$refs.classroom.clearSingleSelect();
+        }
+      },
+      getClassroomList(index) {
+        console.log(this.gradeList[index].code);
+        this.classroomShowList = this.classroomList.filter((item) => { return item.grade == this.gradeList[index].code });
+        if (this.classroomShowList.length == 0) {
+          this.$refs.classroom.clearSingleSelect();
+        }
+      },
       getPageData() {
         let start = ((this.currentPage - 1) * this.pageSize);
         let end = 0;
@@ -121,7 +141,7 @@
       },
       searchData() {
         this.tableLoading = true;
-        this.tableShowData = this.tableData.filter(item => item.account.indexOf(this.serchText) != -1);
+        this.tableShowData = this.tableData.filter(item => item.account.indexOf(this.searchText) != -1);
         this.currentPage = 1;
         this.getPageData();
         this.tableLoading = false;
@@ -241,6 +261,30 @@
           
         }
       },
+      getSchoolData() {
+        this.$api.schoolSetting.findSchoolSystem({
+          Code: this.demoLoginInfo.schoolCode
+        }).then(res => {
+          if (res.error == null) {
+            if (res.result.data.length > 0) {
+              this.schoolData = res.result.data[0];
+            } 
+          }
+        }
+        );
+      },
+      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.classroomShowList] = this.classroomList;
+            }
+          }
+        });
+      },
       initData() {
         this.tableColumns = [
           {
@@ -248,6 +292,12 @@
             width: 80,
             align: 'center'
           },
+          {
+            key: "seatNo",
+            title:this.$t('stuAccount.seatNo'),
+            align: 'center',
+            width: 80
+          },
           {
             key: "account",
             title:this.$t('stuAccount.account'),
@@ -294,6 +344,8 @@
     },
     created() {
       this.initData();
+      this.getSchoolData();
+      this.getClassroom();
     },
     computed: {
     },

+ 19 - 7
TEAMModelOS/ClientApp/view/student-account/add-student/AddStudent.vue

@@ -81,9 +81,12 @@
         <FormItem :label="$t('stuAccount.stuName')" prop="name">
           <Input v-model="studentInfo.name" :placeholder="$t('stuAccount.stuNameHolder')"></Input>
         </FormItem>
-        <FormItem :label="$t('stuAccount.classroomInfo')" prop="classroom">
-          <Select filterable v-model="studentInfo.classroom" style="width:100%" :placeholder="$t('stuAccount.classroomInfoHolder')">
-            <Option v-for="(item,index) in classroomList" :value="item.id" :key="item.id" @click.native="getCurrentClassroom(index)">{{ item.name }}</Option>
+        <FormItem :label="$t('stuAccount.stuSeatNo')" prop="seatNo">
+          <Input type="number" number v-model="studentInfo.seatNo" :min="1" :placeholder="$t('stuAccount.stuSeatNoHolder')"></Input>
+        </FormItem>
+        <FormItem :label="$t('stuAccount.classroomInfo')" prop="classroomName">
+          <Select filterable v-model="studentInfo.classroomName" style="width:100%" :placeholder="$t('stuAccount.classroomInfoHolder')">
+            <Option v-for="(item,index) in classroomList" :value="item.name" :key="item.id" @click.native="getCurrentClassroom(index)">{{ item.name }}</Option>
           </Select>
           <span style="float:right;color:#6DE2C4;cursor:pointer;text-decoration:underline;" @click="createClassroom">{{$t('stuAccount.newClassroom')}}</span>
         </FormItem>
@@ -113,6 +116,9 @@
         <FormItem :label="$t('stuAccount.stuName')" prop="name" v-if="editStudentInfo.length == 1">
           <Input v-model="editStudentInfo[0].name" :placeholder="$t('stuAccount.stuNameHolder')"></Input>
         </FormItem>
+        <FormItem :label="$t('stuAccount.stuSeatNo')" prop="seatNo" v-if="editStudentInfo.length == 1">
+          <Input type="number" number v-model="editStudentInfo[0].seatNo" :min="1" :placeholder="$t('stuAccount.stuSeatNoHolder')"></Input>
+        </FormItem>
         <FormItem :label="$t('stuAccount.classroomInfo')" prop="classroom">
           <Select filterable v-model="editStudentInfo[0].classroom" style="width:100%" :placeholder="$t('stuAccount.classroomInfoHolder')">
             <Option v-for="(item,index) in classroomList" :value="item.id" :key="item.id" @click.native="getCurrentClassroom(index)">{{ item.name }}</Option>
@@ -166,9 +172,11 @@
           account: "",
           password: "",
           name:"",
-          classroom: "",
+          classroomName: "",
+          classroomCode: "",
           period: "",
-          grade:""
+          grade: "",
+          seatNo: null
         },
         ruleValidate: {
           account: [
@@ -177,11 +185,14 @@
           password: [
             { required: true, message: '密码不能为空', trigger: 'blur' }
           ],
-          classroom: [
+          classroomName: [
             { required: true, message: '教室资讯不能为空', trigger: 'blur' }
           ],
           name: [
-            { required: true, message: '教室资讯不能为空', trigger: 'blur' }
+            { required: true, message: '学生姓名不能为空', trigger: 'blur' }
+          ],
+          seatNo: [
+            { required: true, type:'number', message: '学生座位号不能为空', trigger: 'blur' }
           ],
           period: [
             { required: true, message: '学制不能为空', trigger: 'blur' }
@@ -238,6 +249,7 @@
         if (this.bizType == 1) {
           this.studentInfo.period = this.classroomList[index].period;
           this.studentInfo.grade = this.classroomList[index].grade;
+          this.studentInfo.classroomCode = this.classroomList[index].classroomCode;
         } else {
           for (let i = 0; i < this.editStudentInfo.length; i++) {
             this.editStudentInfo[i].period = this.classroomList[index].period;

+ 7 - 4
TEAMModelOS/ClientApp/view/student-account/add-student/ImportStudent.less

@@ -38,21 +38,24 @@
     }
 
     & > &-item:nth-child(2) {
-        color: #1CCC9E;
+        color: #ed6565;
     }
 
     & > &-item:nth-child(3) {
-        color: #E1B551;
+        color: #ed6565;
     }
 
     & > &-item:nth-child(4) {
-        color: #ed6565;
+        color: #1CCC9E;
     }
 
     & > &-item:nth-child(5) {
-        color: #11fd03;
+        color: #E1B551;
     }
 
+    & > &-item:nth-child(6) {
+        color: #11fd03;
+    }
     /*& > &-item:last-child {
         color: #ed6565;
         float: right;

+ 126 - 44
TEAMModelOS/ClientApp/view/student-account/add-student/ImportStudent.vue

@@ -29,21 +29,25 @@
             <span class="table-info-label">{{$t('stuAccount.importInfo1')}}</span>
             <span class="table-info-num">{{totalNum}}</span>
           </div>
-          <div class="table-info-item">
+          <div class="table-info-item" v-if="repeatNum != 0">
             <span class="table-info-label">{{$t('stuAccount.importInfo2')}}</span>
             <span class="table-info-num">{{repeatNum}}</span>
           </div>
-          <div class="table-info-item">
+          <div class="table-info-item"  v-if="seatRepeatNum != 0">
             <span class="table-info-label">{{$t('stuAccount.importInfo3')}}</span>
-            <span class="table-info-num">{{existNum}}</span>
+            <span class="table-info-num">{{seatRepeatNum}}</span>
           </div>
-          <div class="table-info-item">
+          <div class="table-info-item" v-if="noClassroomNum != 0">
             <span class="table-info-label">{{$t('stuAccount.importInfo4')}}</span>
             <span class="table-info-num">{{noClassroomNum}}</span>
           </div>
 
-          <div class="table-info-item">
+          <div class="table-info-item" v-if="existNum != 0">
             <span class="table-info-label">{{$t('stuAccount.importInfo5')}}</span>
+            <span class="table-info-num">{{existNum}}</span>
+          </div>
+          <div class="table-info-item" style="display:none;">
+            <span class="table-info-label">{{$t('stuAccount.importInfo6')}}</span>
             <span class="table-info-num">{{totalNum - repeatNum - existNum}}</span>
           </div>
           <!--<div class="table-info-item">
@@ -55,12 +59,13 @@
             <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>
+            <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>
+            <p :class="row.seatRepeat? 'account-error-tips':''">{{row.seatRepeat ? "错误:座位号重复":"" }}</p>
           </template>
         </Table>
         <p style="margin-top:15px;">{{$t('stuAccount.passwordTips')}}</p>
-        <Button class="confirm-btn confirm-btn-active" :loading="uploadLoading" @click="saveFileData">
+        <Button class="confirm-btn" :class=" isError == 0 ?'confirm-btn-active':''  " :loading="uploadLoading" @click="saveFileData">
           {{$t('stuAccount.submitList')}}
         </Button>
       </div>
@@ -85,9 +90,10 @@
     },
     data() {
       return {
-        totalNum:0,
+        totalNum: 0,
+        seatRepeatNum:0,
         repeatNum: 0,
-        existNum:0,
+        existNum: 0,
         repeatAccounts:[],
         noClassroomNum:0,
         uploadLoading: false,
@@ -104,13 +110,17 @@
           'password',
           'name',
           'classroomName',
-          'classroomCode'
+          'classroomCode',
+          'seatNo'
         ]
       }
     },
     components: {
     },
     computed: {
+      isError() {
+        return this.seatRepeatNum + this.repeatNum + this.existNum + this.noClassroomNum;
+      },
       show: {
         get() {
           return this.isShow;
@@ -123,9 +133,15 @@
     watch: {
     },
     methods: {
+      getSelectInfo() {
+
+      },
+      cancelAll() {
+
+      },
       rowClassName(row, index) {
         let className = ''
-        if (!(this.repeatAccounts.length == 0 || this.repeatAccounts.indexOf(row.account) == -1)) {
+        if (!(this.repeatAccounts.length == 0 || this.repeatAccounts.indexOf(row.account) == -1) || row.seatRepeat) {
           className = className + 'account-error-row-bg ';
         }
         if (row.classroomCode == '' || row.classroomCode == null) {
@@ -188,12 +204,10 @@
           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;
               }
             }
@@ -205,16 +219,17 @@
           }
           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]
+                  if (i != 'seatNo') {
+                    if (typeof item[i] == "number") {
+                      item[i] = item[i] + "";
+                    }
+                    if (item.password == undefined) {
+                      item.password = arr[1]
+                    }
                   }
                 }
                 
@@ -223,25 +238,40 @@
               }
               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);
+            //直接过滤重复账号
+            //this.tableData = this.tableData.filter((item, index, self) => {
+            //  if (accounts.indexOf(item.account) === index) {
+            //    return 1;
+            //  } else {
+            //    return 0;
+            //  }
+            //});
             accounts = accounts.filter((item, index, self) => self.indexOf(item) === index);
-            this.repeatNum = this.totalNum - accounts.length;
-            
-
+            this.repeatNum = this.totalNum - accounts.length + this.repeatAccounts.length;
+            //根据教室Code GroupBy,判断班级座位号是否重复
+            console.log("++++++++++");
+            let classStu = this.groupBy(this.tableData, 'classroomCode');
+            for (let item of classStu) {
+              let seatNoArr = item.map(item => { return item.seatNo });
+              for (let index in item) {
+                let flag = seatNoArr.indexOf(item[index]['seatNo'])
+                if (flag != index) {
+                  let tableIndex = this.getIndex(this.tableData, item[flag]);
+                  if (this.tableData[tableIndex].seatRepeat != true) {
+                    this.seatRepeatNum++;
+                    this.tableData[tableIndex].seatRepeat = true;
+                  }
+                  tableIndex = this.getIndex(this.tableData, item[index]);
+                  this.tableData[tableIndex].seatRepeat = true;
+                  this.seatRepeatNum++;
+                }
+              }
+            }
             //筛选没有教室账号
             let noRoom = this.tableData.filter(item => { return (item.classroomCode == '' || item.classroomCode == null) });
             this.noClassroomNum = noRoom.length;
@@ -257,19 +287,65 @@
           this.showRemoveFile = true;
         }
       },
+      groupBy(array, key) {
+        const groups = {}
+        array.forEach(function (item) {
+          const group = JSON.stringify(item[key])
+          groups[group] = groups[group] || []
+          groups[group].push(item)
+        })
+        return Object.keys(groups).map(function (group) {
+          return groups[group]
+        })
+      },
+      /*
+      *获取对象在对象数组的中index
+      */
+      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;
+      },
+
+      /*
+      * 判断两个json对象是否相同
+      */
+      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;
+      },
       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)
+        if (this.isError == 0) {
+          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.initData();
+          this.uploadLoading = false;
+        } else {
+          this.$Message.error(this.$t('stuAccount.importTips12'));
         }
-        this.$emit("importStudentInfo", {
-          data: this.tableData
-        });
-        this.initData();
-        this.uploadLoading = false;
+        
       },
       cancel() {
         this.initData();
@@ -281,6 +357,7 @@
         this.totalNum = 0;
         this.repeatNum = 0;
         this.existNum = 0;
+        this.seatRepeatNum = 0;
         this.repeatAccounts = [];
         this.noClassroomNum = 0;
         this.uploadLoading =  false;
@@ -295,6 +372,11 @@
             width: 80,
             align: 'center'
           },
+          {
+            title: this.$t('stuAccount.seatNo'),
+            key: 'seatNo',
+            width: 80,
+          },
           {
             title: this.$t('stuAccount.account'),
             key:'account'

+ 1 - 1
TEAMModelOS/ClientApp/view/student-analysis/total-analysis/TestAnalysis/QuestionList.css

@@ -32,7 +32,7 @@
 
     .ql-left-box .btn-back {
         position: absolute;
-        right: 15px;
+        right: 24px;
         top: 20px;
         font-size: 14px;
         cursor: pointer;

+ 13 - 13
TEAMModelOS/ClientApp/view/student-analysis/total-analysis/TestAnalysis/QuestionList.vue

@@ -5,7 +5,7 @@
       <!--<p style="font-size:28px;text-align:center;margin:20px 0">芳草小学2019年5月期中考试数学试卷</p>
   <p style="font-size:16px;text-align:center">考试时间:120分钟&nbsp;&nbsp;&nbsp;出卷人:张纪中</p>-->
 
-      <span class="btn-back" @click="handleBackTo" ref="btnBack"><Icon type="ios-arrow-back" />返回</span>
+      <span class="btn-back" @click="handleBackTo" ref="btnBack"><Icon type="ios-arrow-back" />{{$t('totalAnalysis.ql_text13')}}</span>
 
       <div class="ql-item" v-for="(question,index) in questionList">
         <div>
@@ -18,7 +18,7 @@
           </div>
           <div class="item-question-score">
             <span class="item-type">{{question.questionType}}</span>
-            <span class="item-type" style="background: #05b454;">{{question.score}}</span>
+            <span class="item-type" style="background: #05b454;">{{question.score}}{{$t('totalAnalysis.ql_text8')}}</span>
           </div>
         </div>
         <div class="item-option-wrap">
@@ -51,22 +51,22 @@
 
         <Collapse simple @on-change="handleCollapseChange" v-model="activeCollapseIndex">
           <Panel :name="index+'answer'">
-            <span>查看答案及解析</span>
+            <span>{{$t('totalAnalysis.ql_text9')}}</span>
             <div class="answerAndExplain" slot="content" style="margin-top:10px;margin-left: 25px;">
               <div class="item-answer" v-show="question.type != 'Compose'">
-                <span class="item-header-title">【参考答案】</span>
+                <span class="item-header-title">【{{$t('totalAnalysis.ql_text11')}}】</span>
                 <span v-html="question.answer[0] || question.answer" v-if="question.type == 'Subjective'"></span>
                 <span :class="[ question.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in question.answer" v-else-if="question.type == 'Complete'" v-html="answer"></span>
                 <span :class="[ question.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in question.answer" v-else>{{answer}}</span>
               </div>
               <div class="item-explain" v-show="question.type != 'Compose'">
-                <div class="item-header-title">【答题解析】</div>
+                <div class="item-header-title">【{{$t('totalAnalysis.ql_text12')}}】</div>
                 <div v-html="question.explain"></div>
               </div>
             </div>
           </Panel>
           <Panel :name="index+''">
-            <span>查看数据分析</span>
+            <span>{{$t('totalAnalysis.ql_text10')}}</span>
             <div class="answerAndExplain" slot="content" style="margin-top:10px" v-if="collapseList.indexOf(index.toString()) > -1">
               <Table :columns="dataColumns" :data="tableData.filter((item,index2) => index2 == index)"></Table>
               <Table :columns="optionColumns" :data="optionsData" style="margin-top:20px"></Table>
@@ -85,41 +85,41 @@
     <!-- 右侧题目列表题型概览 -->
     <div class='ql-right-box' ref="rightBox">
       <div class="ql-right-score">
-        试卷总分 :<span>100分</span>
+        {{$t('totalAnalysis.ql_text1')}} :<span>100 {{$t('totalAnalysis.ql_text8')}}</span>
       </div>
       <div class="ql-right-list">
         <div class="ql-right-part" v-if="SingleList.length">
-          <span class="ql-right-part-title"><span class="ql-line"></span>单项选择题({{sumArr(SingleList.map(item => item.score))}}分)</span>
+          <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text2')}}({{sumArr(SingleList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
           <div class="ql-right-items">
             <span class="ql-right-item" v-for="(item,index) in SingleList" :key="index" @click="handleItemClick(item,$event)">{{index + 1}}</span>
           </div>
         </div>
         <div class="ql-right-part" v-if="MultipleList.length">
-          <span class="ql-right-part-title"><span class="ql-line"></span>多项选择题({{sumArr(MultipleList.map(item => item.score))}}分)</span>
+          <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text3')}}({{sumArr(MultipleList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
           <div class="ql-right-items">
             <span class="ql-right-item" v-for="(item,index) in MultipleList" :key="index" @click="handleItemClick(item,$event)">{{index + 1}}</span>
           </div>
         </div>
         <div class="ql-right-part" v-if="JudgeList.length">
-          <span class="ql-right-part-title"><span class="ql-line"></span>判断题({{sumArr(JudgeList.map(item => item.score))}}分)</span>
+          <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text4')}}({{sumArr(JudgeList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
           <div class="ql-right-items">
             <span class="ql-right-item" v-for="(item,index) in JudgeList" :key="index" @click="handleItemClick(item,$event)">{{index + 1}}</span>
           </div>
         </div>
         <div class="ql-right-part" v-if="CompleteList.length">
-          <span class="ql-right-part-title"><span class="ql-line"></span>填空题({{sumArr(CompleteList.map(item => item.score))}}分)</span>
+          <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text5')}}({{sumArr(CompleteList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
           <div class="ql-right-items">
             <span class="ql-right-item" v-for="(item,index) in CompleteList" :key="index" @click="handleItemClick(item,$event)">{{index + 1}}</span>
           </div>
         </div>
         <div class="ql-right-part" v-if="SubjectiveList.length">
-          <span class="ql-right-part-title"><span class="ql-line"></span>问答题({{sumArr(SubjectiveList.map(item => item.score))}}分)</span>
+          <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text6')}}({{sumArr(SubjectiveList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
           <div class="ql-right-items">
             <span class="ql-right-item" v-for="(item,index) in SubjectiveList" :key="index" @click="handleItemClick(item,$event)">{{index + 1}}</span>
           </div>
         </div>
         <div class="ql-right-part" v-if="ComposeList.length">
-          <span class="ql-right-part-title"><span class="ql-line"></span>综合题({{sumArr(ComposeList.map(item => item.score))}}分)</span>
+          <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text7')}}({{sumArr(ComposeList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
           <div class="ql-right-items">
             <span class="ql-right-item" v-for="(item,index) in ComposeList" :key="index" @click="handleItemClick(item,$event)">{{index + 1}}</span>
           </div>

+ 19 - 11
TEAMModelOS/ClientApp/view/student-analysis/total-analysis/TestAnalysis/TestAnalysis.css

@@ -43,6 +43,12 @@
     /*border-bottom:1px solid #595959;*/
 }
 
+    .scatter-statistics .index-box {
+        width:150px;
+        word-break:break-all;
+    }
+
+
     .scatter-statistics .scatter-table-line span {
         text-align: center;
         width: 150px;
@@ -62,23 +68,25 @@
     }
 
     .scatter-statistics .scatter-exercise-index {
-        padding:3px 5px;
-        cursor:pointer;
-        font-size:16px;
-        margin:3px;
-        /*color:aqua;*/
-        /*border-bottom:1px solid aqua;*/
-    }
-
-    .scatter-statistics .scatter-exercise-index:hover {
         padding: 3px 5px;
         cursor: pointer;
+        white-space: nowrap;
+        line-height:30px;
         font-size: 16px;
         margin: 3px;
-        color: aqua;
-        border-bottom: 1px solid aqua;
+        /*color:aqua;*/
+        /*border-bottom:1px solid aqua;*/
     }
 
+        .scatter-statistics .scatter-exercise-index:hover {
+            padding: 3px 5px;
+            cursor: pointer;
+            font-size: 16px;
+            margin: 3px;
+            background: #018b99 !important;
+            border-radius:50%;
+        }
+
     .fl-col-center {
         display: flex;
         flex-direction: column;

+ 6 - 5
TEAMModelOS/ClientApp/view/student-analysis/total-analysis/TestAnalysis/TestAnalysis.vue

@@ -18,28 +18,28 @@
           <span>A</span>
           <span class="scatter-explain" :title="$t('totalAnalysis.ta_text6')">{{$t('totalAnalysis.ta_text6')}}</span>
           <span>{{A1List.length}}</span>
-          <span><span v-for="item in A1List" class="scatter-exercise-index" @click="handleIndexClick(item)">{{item}}</span></span>
+          <div class="index-box"><span v-for="item in A1List" class="scatter-exercise-index" @click="handleIndexClick(item)">{{item > 9 ? item : '0' + item}}</span></div>
         </div>
         <Divider />
         <div class="scatter-table-line">
           <span>A`</span>
           <span class="scatter-explain" :title="$t('totalAnalysis.ta_text7')">{{$t('totalAnalysis.ta_text7')}}</span>
           <span>{{A2List.length}}</span>
-          <span><span v-for="item in A2List" class="scatter-exercise-index" @click="handleIndexClick(item)">{{item}}</span></span>
+          <div class="index-box"><span v-for="item in A2List" class="scatter-exercise-index" @click="handleIndexClick(item)">{{item > 9 ? item : '0' + item}}</span></div>
         </div>
         <Divider />
         <div class="scatter-table-line">
           <span>B</span>
           <span class="scatter-explain" :title="$t('totalAnalysis.ta_text8')">{{$t('totalAnalysis.ta_text8')}}</span>
           <span>{{B1List.length}}</span>
-          <span><span v-for="item in B1List" class="scatter-exercise-index" @click="handleIndexClick(item)">{{item}}</span></span>
+          <div class="index-box"><span v-for="item in B1List" class="scatter-exercise-index" @click="handleIndexClick(item)">{{item > 9 ? item : '0' + item}}</span></div>
         </div>
         <Divider />
         <div class="scatter-table-line">
           <span>B`</span>
           <span class="scatter-explain" :title="$t('totalAnalysis.ta_text9')">{{$t('totalAnalysis.ta_text9')}}</span>
           <span>{{B2List.length}}</span>
-          <span><span v-for="item in B2List" class="scatter-exercise-index" @click="handleIndexClick(item)">{{item}}</span></span>
+          <div class="index-box"><span v-for="item in B2List" class="scatter-exercise-index" @click="handleIndexClick(item)">{{item > 9 ? item : '0' + item}}</span></div>
         </div>
       </div>
       </Col>
@@ -323,7 +323,8 @@
         indexDomList.forEach(item => {
           item.style.background = "transparent";
         })
-        hignlightIndexDom[0].style.background = "#ee4473";
+        hignlightIndexDom[0].style.background = "#018b99";
+        hignlightIndexDom[0].style.borderRadius = "50%";
       },
 
       handleIndexClick(index) {

+ 21 - 0
TEAMModelOS/ClientApp/view/student-analysis/total-analysis/index.css

@@ -213,6 +213,27 @@ body, html, .total-container {
     display: none;
 }
 
+
+.total-container .back-to-top {
+    position:fixed;
+    right:50px;
+    bottom:30px;
+    height:40px;
+    width:50px;
+    background:#595959;
+    z-index:99999;
+    cursor:pointer;
+}
+
+.total-container .back-to-top:hover {
+    background:rgb(128,128,128);
+}
+
+    .total-container .back-to-top .ivu-icon {
+        font-size:26px;
+        color:white;
+    }
+
 .fl-col-center {
     display: flex;
     flex-direction: column;

+ 22 - 11
TEAMModelOS/ClientApp/view/student-analysis/total-analysis/index.vue

@@ -8,6 +8,7 @@
       <BaseHeader></BaseHeader>
     </div>
 
+
     <div class="total-body">
       <!-- 左侧菜单 -->
       <div class="slide-menu">
@@ -55,6 +56,9 @@
 
       <!-- 右侧数据展示区域 -->
       <div class="total-content" ref="dataContainer">
+        <div class="back-to-top fl-col-center" title="返回顶部" v-if="isShowBackToTop" @click="handleBackToTop">
+          <Icon type="ios-arrow-up" />
+        </div>
         <Spin fix v-show="contentLoading"></Spin>
         <div class="basic-info" v-if="!isShowEvaluations">
           <p>
@@ -68,13 +72,7 @@
             <span class="info-date">{{$t('totalAnalysis.text8')}}:<span style="color:#fff">{{currentExamItem.date}}</span></span>
           </p>
           <div class="basic-tools">
-            <!--<span v-show="dataSelectIndex != 0" class="select-title">选择学科:</span>
-            <Select v-show="dataSelectIndex != 0" v-model="subjectSelectVal" style="width:150px">
-              <Option v-for="(item,index) in subjectList" :value="index" :key="index">{{ item.name }}</Option>
-            </Select>-->
-            <!--<Input v-show="dataSelectIndex != 0" v-model="searchValue" placeholder="输入学生姓名或学号..." style="width: 200px" search @on-search="handleSearch" />-->
             <span class="basic-tool-export" @click="handleExportTables"> {{$t('totalAnalysis.exportTable')}} <Icon type="md-archive" /></span>
-
           </div>
         </div>
         <div class="data-select" v-if="!isShowQuestions" ref="dataSelect">
@@ -84,11 +82,11 @@
             <span :class="this.$route.path.indexOf('/total/test') > -1 ? 'data-select-active' : ''" @click="handleDataSelect('2')">{{$t('totalAnalysis.module3')}}</span>
             <span :class="this.$route.path.indexOf('/total/knowledge') > -1 ? 'data-select-active' : ''" @click="handleDataSelect('3')">{{$t('totalAnalysis.module4')}}</span>
           </div>
-            <span style="float:right;margin-bottom:4px;"  v-show="dataSelectIndex != 0">
-              <span class="select-title">当前学科:</span>
-              <Select  v-model="subjectSelectVal" style="width:150px" @on-change="handleSubjectChange">
-                <Option v-for="(item,index) in getSubjectList" :value="index" :key="index" :label="item"></Option>
-              </Select>
+          <span style="float:right;margin-bottom:4px;" v-show="dataSelectIndex != 0">
+            <span class="select-title">{{$t('totalAnalysis.currentSubject')}}:</span>
+            <Select v-model="subjectSelectVal" style="width:150px" @on-change="handleSubjectChange">
+              <Option v-for="(item,index) in getSubjectList" :value="index" :key="index" :label="item"></Option>
+            </Select>
           </span>
         </div>
         <div class="data-container" style="position:relative" ref="routerView">
@@ -130,6 +128,7 @@
         dataLoading:false,
         dataSelectIndex: 0 ,
         menuIndex: 0,
+        isShowBackToTop:false,
         isShowQuestions:false,
         isShowEvaluations:false,
         isSubMenuShow: false,
@@ -251,6 +250,11 @@
         this.isExportTables = true
       },
 
+      //返回顶部
+      handleBackToTop() {
+        this.scrollToTop(this.$refs.dataContainer, 0, 200);
+      },
+
       //点击搜索或者按下回车键响应
       handleSearch() {
         if (this.searchValue) {
@@ -274,6 +278,13 @@
     mounted() {
       let examIndex = this.$route.query.index;
 
+
+      this.$refs.dataContainer.addEventListener('scroll', () => {
+        this.isShowBackToTop = this.$refs.dataContainer.scrollTop >= 400 ? true : false;
+      }, false)
+
+
+
       //如果路由跳转到成绩分析页面带有考试序号参数则跳转到当前考试
       if (examIndex || examIndex == 0) {
         this.currentExamItem = this.$refs.examListRef.examList[this.$route.query.index];

+ 180 - 7
TEAMModelOS/Controllers/Analysis/ChangeController.cs

@@ -7,6 +7,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using TEAMModelOS.Helper.Common.FileHelper;
+using TEAMModelOS.Model.Evaluation.Models.CosmosModels;
 using TEAMModelOS.Model.EvaluaTion.Dtos;
 using TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse;
 using TEAMModelOS.SDK.Extension.JsonPath;
@@ -73,20 +74,192 @@ namespace TEAMModelOS.Controllers.Analysis
             // 获取系统路径
             string contentRootPath = _hostingEnvironment.ContentRootPath;
             identity = "IES/adas";
-            string query = "$.info";
-            JObject parsedJson = JObject.Parse(identity);
+            //string query = "$.info";
+            //int countClasses = 0; 
+            //string queryClass = "$member.1.item_answer[*]";
+            string query = "$.exercise[*]";
+            string queryInfo = "$.info";
+            string queryPoint = "$.testpaper.item[*]";
+            //string queryInfo = "$.exercise.info[*]";
+            string data = FileTool.getJson(contentRootPath, identity);
+            data = FileTool.UnicodeToString(data);
+            JObject parsedJson = JObject.Parse(data);
             JsonPathContext context = new JsonPathContext
             { ValueSystem = new JsonNetValueSystem() };
             List<dynamic> papers = context.SelectNodes(parsedJson,
             query).Select(node => node.Value).ToList();
+            List<dynamic> info = context.SelectNodes(parsedJson,
+            queryInfo).Select(node => node.Value).ToList();
+            List<dynamic> Itempoint = context.SelectNodes(parsedJson,
+            queryPoint).Select(node => node.Value).ToList();
+
+            int m = 0;
+            //人数总和
+            int Count = 0;
+            //起始坐标
+            int Strat = 0;
+            // 初始化学生人数
+            int Stus = 0;
+            SimpleExam simple = new SimpleExam();
+            List<List<List<int>>> ClassPoint = new List<List<List<int>>>();
+            List<List<int>> StuPoint = new List<List<int>>();
+            List<string> StuIds = new List<string>();
+            List<Dictionary<object, int[]>> Classes = new List<Dictionary<object, int[]>>();
+            Dictionary<object, object> ListInfo = new Dictionary<object, object>();
+            List<int> points = new List<int>();
+            //配分数组
+            Itempoint.ForEach(p =>
+            {
+                string pt = p.point;
+                points.Add(int.Parse(pt));
+            });
+            //基本信息
+            info.ForEach(e => {
+                simple.Name = e.test_name;
+                simple.Time = e.test_date;
+                //ListInfo.Add("Name",e.test_name);
+                //ListInfo.Add("Time", e.test_date);
+            });
+            papers.ForEach(x =>
+            {
+            
+            //var c = papers[i].member;
+            string stu = x.info.stucount;
+            int k = int.Parse(stu);
+            Dictionary<object, int[]> map = new Dictionary<object, int[]>();
+                int[] Range = new int[2];
+                //int[] EachRange = new int[2];
+                
+
+
+                //List<List<int>> StuPoint = new List<List<int>>();
+                for (int j = 1; j <= k; j++)
+                {
+                    string men = x.member + "";
+                    JObject jArray = JObject.Parse(men);
+                    List<int> point = new List<int>();
+                    //List<string> stuId = new List<string>();
+                    string queryClass = "$." + j + ".item_answer[*]";
+                    string queryStu = "$." + j + ".info";
+                    List<dynamic> answers = context.SelectNodes(jArray,
+                    queryClass).Select(node => node.Value).ToList();
+                    //学生ID集合
+                    List<dynamic> studentIds = context.SelectNodes(jArray,
+                    queryStu).Select(node => node.Value).ToList();
+
+                    if (answers.Count == 0)
+                    {
+                        StuIds.Add("0");
+                        k++;
+                    }
+                    else {
+                        studentIds.ToList<dynamic>().ForEach(s =>
+                        {
+                            string id = s.studentid;
+                            StuIds.Add(id);
+                        });
+                    }
+                    answers.ToList<dynamic>().ForEach(p =>
+                    {
+                        string pt = p.ans_point;
+                        point.Add(int.Parse(pt));
+                    });
+                    StuPoint.Add(point);
+                    Stus++;
+                }
+                //每次人数累加得到实际总人数
+                Count += Stus;
+                if (m == 0)
+                {
+                    Strat = Stus;
+                    Range[0] = 0;
+                    Range[1] = Stus - 1;
+                }
+                else
+                {
+                    Range[0] = Count - Stus;
+                    Range[1] = Count - 1;
+                }
+                map.Add(x.info.class_name, Range);
+                Classes.Add(map);
+                m++;
+                //初始化每个班级人数
+                Stus = 0;
+                
+                //ClassPoint.Add(StuPoint);
+            });
+            simple.Classes = Classes;
+            simple.Ids = StuIds;
+            simple.Point = points;
+            simple.Result = StuPoint;
             JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
-            //string data = FileTool.getJson(contentRootPath, identity);
-            //data = FileTool.UnicodeToString(data);
-            //List<MemberAnswer> obj = MessagePackHelper.JsonToObject<List<MemberAnswer>>(data);
-            //_examInfoService.SaveOrUpdate(obj, "cn");
-            return builder.Data(papers).build();
+            _examInfoService.SaveToCosmos(simple);
+            
+            return builder.Data(simple).build();
             //return builder.build();
         }
 
+
+        [HttpGet("SaveStuInfo")]
+        public BaseJosnRPCResponse SaveStuInfo(string identity)
+
+        {
+            // 获取系统路径
+            string contentRootPath = _hostingEnvironment.ContentRootPath;
+            identity = "IES/adas";
+            string query = "$.exercise[*]";
+            //string queryInfo = "$.exercise.info[*]";
+            string data = FileTool.getJson(contentRootPath, identity);
+            data = FileTool.UnicodeToString(data);
+            JObject parsedJson = JObject.Parse(data);
+            JsonPathContext context = new JsonPathContext
+            { ValueSystem = new JsonNetValueSystem() };
+            List<dynamic> papers = context.SelectNodes(parsedJson,
+            query).Select(node => node.Value).ToList();
+            List<StuInfo> list = new List<StuInfo>();
+            string SchoolCode = Guid.NewGuid().ToString();
+            papers.ForEach(x =>
+            {
+                string GradeCode = Guid.NewGuid().ToString();
+                string ClassRoomCode = Guid.NewGuid().ToString();
+                //var c = papers[i].member;
+                string stu = x.info.stucount;
+                int k = int.Parse(stu);
+                
+                for (int j = 1; j <= k; j++)
+                {
+                    
+                    string men = x.member + "";
+                    JObject jArray = JObject.Parse(men);
+                    List<int> point = new List<int>();
+                    string queryClass = "$." + j + ".info";
+                    List<dynamic> StuInfo = context.SelectNodes(jArray,
+                    queryClass).Select(node => node.Value).ToList();
+                    StuInfo.ToList<dynamic>().ForEach(p =>
+                    {
+                        StuInfo Stu = new StuInfo
+                        {
+                            Id = Guid.NewGuid().ToString(),
+                            Name = p.name,
+                            StudentId = "101010#" + p.studentid,
+                            SeatNo = p.seatno,
+                            SchoolCode = SchoolCode,
+                            GradeCode = GradeCode,
+                            ClassroomCode = ClassRoomCode
+
+                        };
+                        list.Add(Stu);
+                    });
+                }
+
+
+                //ClassPoint.Add(StuPoint);
+            });
+
+            JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
+            _examInfoService.SaveListToCosmos(list);
+            return builder.Data(list).build();
+        }
+
     }
 }

+ 1 - 1
TEAMModelOS/JsonFile/IES/adas.json

@@ -1,4 +1,4 @@
-{
+{
 	"info": {
 		"language": "zh-CN",
 		"report_type": "Principal_Teacher",