Browse Source

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

CrazyIter_Bin 4 years ago
parent
commit
0fed189a71
65 changed files with 1307 additions and 1888 deletions
  1. 62 0
      TEAMModelFunction/TriggerExam.cs
  2. 4 0
      TEAMModelOS.SDK/Models/Cosmos/School/ExamInfo.cs
  3. 3 0
      TEAMModelOS.SDK/Models/Cosmos/School/ExamResult.cs
  4. 0 59
      TEAMModelOS/ClientApp/src/common/BaseAudioPlayer.vue
  5. 1 1
      TEAMModelOS/ClientApp/src/common/BaseLayout.vue
  6. 0 573
      TEAMModelOS/ClientApp/src/common/BaseMock.vue
  7. 16 10
      TEAMModelOS/ClientApp/src/common/BaseMyCanvas.vue
  8. 3 3
      TEAMModelOS/ClientApp/src/common/BaseNotification.vue
  9. 3 3
      TEAMModelOS/ClientApp/src/common/BaseSelectSchool.vue
  10. 18 18
      TEAMModelOS/ClientApp/src/common/BaseUserPoptip.vue
  11. 0 41
      TEAMModelOS/ClientApp/src/common/BaseVideoPlayer.vue
  12. 2 3
      TEAMModelOS/ClientApp/src/common/EmptyData.vue
  13. 5 6
      TEAMModelOS/ClientApp/src/common/ImportExcel.vue
  14. 0 408
      TEAMModelOS/ClientApp/src/common/NewUploadFile.vue
  15. 2 2
      TEAMModelOS/ClientApp/src/common/UploadFile.vue
  16. 1 1
      TEAMModelOS/ClientApp/src/common/VideoPlayer2.vue
  17. 1 1
      TEAMModelOS/ClientApp/src/components/evaluation/ExerciseList.less
  18. 1 1
      TEAMModelOS/ClientApp/src/components/evaluation/ExerciseList.vue
  19. 3 3
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseJudge.vue
  20. 1 1
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseProgress.vue
  21. 0 12
      TEAMModelOS/ClientApp/src/components/selflearn/ExerciseList.vue
  22. 1 1
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseEntryLine.vue
  23. 2 2
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseKnowledgeRadar.vue
  24. 1 1
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseLevelRadar.vue
  25. 32 23
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseMyTable.vue
  26. 5 3
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseScatter.vue
  27. 210 0
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseScoreRateBar.vue
  28. 5 3
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseTestScatter.vue
  29. 1 1
      TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue
  30. 1 1
      TEAMModelOS/ClientApp/src/components/vote/BaseVoteTable.vue
  31. 13 1
      TEAMModelOS/ClientApp/src/locale/lang/en-US/system.js
  32. 6 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/evaluation.js
  33. 13 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/system.js
  34. 11 6
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/totalAnalysis.js
  35. 34 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/utils.js
  36. 6 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/evaluation.js
  37. 13 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/system.js
  38. 12 7
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/totalAnalysis.js
  39. 33 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/utils.js
  40. 1 0
      TEAMModelOS/ClientApp/src/service/User.js
  41. 1 0
      TEAMModelOS/ClientApp/src/utils/editorTools.js
  42. 2 2
      TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue
  43. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseCreateChild.vue
  44. 2 5
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseEditExercise.vue
  45. 2 2
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseExerciseList.vue
  46. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/components/BasePointPie.vue
  47. 1 2
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue
  48. 4 4
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseMultiple.vue
  49. 2 2
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue
  50. 1 1
      TEAMModelOS/ClientApp/src/view/learnactivity/ManualCreate.vue
  51. 1 1
      TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue
  52. 10 5
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/AchievementAnalysis.vue
  53. 532 506
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/EarlyWarning.vue
  54. 36 12
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/EntryTables.vue
  55. 2 1
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.less
  56. 97 83
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.vue
  57. 1 1
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/KnowledgeAnalysis/ScoreDetails.vue
  58. 37 26
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/ScatterAnalysis/ScatterAnalysis.vue
  59. 2 2
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/TestAnalysis/TestAnalysis.vue
  60. 11 6
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/index.less
  61. 12 9
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/index.vue
  62. 10 6
      TEAMModelOS/Controllers/Analysis/AnalysisController.cs
  63. 1 0
      TEAMModelOS/Controllers/Analysis/ClassAys.cs
  64. 3 0
      TEAMModelOS/Controllers/Analysis/StudentAys.cs
  65. 9 9
      TEAMModelOS/Controllers/Common/ExamController.cs

+ 62 - 0
TEAMModelFunction/TriggerExam.cs

@@ -3,6 +3,7 @@ using Azure.Messaging.ServiceBus;
 using Microsoft.Azure.Documents;
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Text;
 using System.Text.Json;
 using System.Threading.Tasks;
@@ -327,6 +328,43 @@ namespace TEAMModelFunction
                         await createClassResultAsync(info, examClassResults, subject, fno, _azureCosmos);
                         fno++;
                     }
+                    //计算单次考试简易统计信息
+                    List<ExamResult> examResults = new List<ExamResult>();
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamResult>(
+                                       queryText: $"select value(c) from c where c.examId  = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamResult-{info.id}") }))
+                    {
+                        examResults.Add(item);
+                    }
+                    //记录某次考试所有学生得分总分
+                    double score = 0;
+                    double allScore = 0;
+                    int stuCount = 0;
+                    List<string> losStu = new List<string>();
+                    //先与第一个值取并集
+                    if (examResults.Count >0 ) {
+                        losStu.Union(examResults[0].lostStus);
+                        foreach (ExamResult examResult in examResults)
+                        {
+                            if (info.id == examResult.examId)
+                            {
+                                foreach (List<double> sc in examResult.studentScores)
+                                {
+                                    score += sc.Sum();
+                                }
+                                stuCount = examResult.studentIds.Count;
+                            }
+                            //取交集
+                            losStu = losStu.Intersect(examResult.lostStus).ToList();
+                        }
+                    }                                      
+                    double ascore = stuCount > 0 ? Math.Round(score * 1.0 / stuCount, 2) : 0;
+                    foreach (PaperSimple simple in info.papers)
+                    {
+                        allScore += simple.point.Sum();
+                    }
+                    info.sRate = allScore > 0 ? Math.Round(ascore / allScore * 100,2) : 0;
+                    info.lostStu = losStu;
+                    await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<ExamInfo>(info, info.id, new Azure.Cosmos.PartitionKey(info.code));
                     //ActivityData data;
                     if (info.scope == "school")
                     {
@@ -376,19 +414,38 @@ namespace TEAMModelFunction
             //人数总和
             int Count = 0;
             int m = 0;
+            double score = 0;
+            double allScore = info.papers[no].point.Sum();
             List<ClassRange> classRanges = new List<ClassRange>();
+            List<string> lostStu = new List<string>();
+            List<double> csRate = new List<double>();
             foreach (ExamClassResult classResult in examClassResults)
             {
+                double classSrate = 0;
                 if (classResult.subjectId.Equals(subject.id))
                 {
+                    //记录缺考学生索引位置
+                    int index = 0;
                     foreach (List<double> scores in classResult.studentScores)
                     {
                         List<double> newScores = new List<double>();
+                        int count = 0;
                         foreach (double sc in scores) {
                             newScores.Add(sc > -1 ? sc : 0);
+                            if(sc == -1) {
+                                count++;
+                            }
                         }
+                        if (count == scores.Count) {
+                            lostStu.Add(classResult.studentIds[index]);
+                            //mcount++;
+                        }
+                        classSrate += newScores.Sum();
+                        score += newScores.Sum();
                         result.studentScores.Add(newScores);
+                        index++;
                     }
+
                     //处理班级信息
                     ClassRange range = new ClassRange();
                     range.id = classResult.info.id;
@@ -415,8 +472,12 @@ namespace TEAMModelFunction
                     {
                         result.studentIds.Add(id);
                     }
+                    csRate.Add(result.studentIds.Count > 0 ? Math.Round(classSrate * 1.0 / classResult.studentIds.Count, 2) : 0 / allScore);
                 }
             }
+            result.csRate = csRate;
+            result.lostStus = lostStu;
+            result.sRate =result.studentIds.Count> 0 ? Math.Round(score *1.0 / result.studentIds.Count ,2 ): 0 / allScore;
             result.classes = classRanges;
             result.code = "ExamResult-" + info.id;
             result.school = info.school;
@@ -429,6 +490,7 @@ namespace TEAMModelFunction
             result.scope = info.scope;
             result.name = info.name;
             result.time = info.startTime;
+
             await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").UpsertItemAsync(result, new Azure.Cosmos.PartitionKey($"ExamResult-{info.id}"));
 
         }

+ 4 - 0
TEAMModelOS.SDK/Models/Cosmos/School/ExamInfo.cs

@@ -83,6 +83,10 @@ namespace TEAMModelOS.SDK.Models
         /// TTL删除改变状态使用
         /// </summary>
         public int? status { get; set; } = 0;
+        //得分率
+        public double sRate { get; set; }
+        //缺考人数
+        public List<string> lostStu { get; set; } = new List<string>();
     }
     public class Custom {
         public string id { get; set; }

+ 3 - 0
TEAMModelOS.SDK/Models/Cosmos/School/ExamResult.cs

@@ -36,6 +36,9 @@ namespace TEAMModelOS.SDK.Models
         public string examId { get; set; }
         public string school { get; set; }
         public int year { get; set; }
+        public double sRate { get; set; }
+        public List<double> csRate { get; set; } = new List<double>();
+        public List<string> lostStus { get; set; } = new List<string>();
     }
     public class ClassRange {
 

+ 0 - 59
TEAMModelOS/ClientApp/src/common/BaseAudioPlayer.vue

@@ -1,59 +0,0 @@
-<template>
-	<div class="audio-container">
-		<!-- <audio :src="audioSrc" controls="controls"></audio> -->
-		<p style="margin-left: 15px;margin-bottom: 10px;">{{ audioName }}</p>
-		<!-- <AudioPlayer ref="audioRef" :audio-list="audioList":show-prev-button="false" :show-next-button="false"/> -->
-
-		<vue-audio-native ref="audioRef" size="default" :url="audioSrc" :showDownload="false" autoplay></vue-audio-native>
-	</div>
-</template>
-
-<script>
-	export default {
-		name: 'audioPlayer',
-		props: {
-			audioSrc: {
-				type: String,
-				default: ''
-			},
-			audioName: {
-				type: String,
-				default: ''
-			}
-		},
-		data() {
-			return {
-				audioList: []
-			}
-		},
-		created() {
-			// this.getFileSas(this.audioSrc)
-			
-		},
-		methods: {
-			async getFileSas(url){
-				const fileSas = await this.$tools.getFileSas({params:url})
-				console.log(fileSas)
-				this.audioSrc = this.audioSrc + fileSas
-			},
-			onCloseAudio() {
-				this.$refs.audioRef.onPause()
-			},
-			onPlayAudio() {
-				this.$refs.audioRef.onPlay()
-			}
-		},
-		watch: {
-			audioSrc: {
-				handler(n) {
-					this.audioList = []
-					this.audioList.push(n)
-				},
-				immediate: true
-			}
-		}
-	}
-</script>
-<style>
-
-</style>

+ 1 - 1
TEAMModelOS/ClientApp/src/common/BaseLayout.vue

@@ -120,7 +120,7 @@ export default {
                         // },
                         {
                             icon: 'iconfont icon-kecheng',
-                            name: '课程管理',
+                            name: this.$t('system.menu.cusMgt'),
                             router: '/home/NewCusMgt',
                             tag: '',
                             role: 'admin',

+ 0 - 573
TEAMModelOS/ClientApp/src/common/BaseMock.vue

@@ -1,573 +0,0 @@
-<template>
-	<div>
-		<div style="display: flex;flex-direction: column;">
-			<span style="margin: 20px 2px;">选择活动类型</span>
-			<Select v-model="acType">
-				<Option :value="0">作业活动</Option>
-				<Option :value="1">投票活动</Option>
-				<Option :value="2">问卷活动</Option>
-				<Option :value="3">评测活动</Option>
-				<Option :value="4">编序式学习</Option>
-				<Option :value="5">学习单元</Option>
-			</Select>
-		</div>
-		<div style="display: flex;flex-direction: column;">
-			<span style="margin: 20px 2px;">输入活动ID</span>
-			<Input v-model="acId" placeholder=""></Input>
-		</div>
-		<div style="margin-top: 30px;">
-			<Button type="success" style="width:100%" @click="onMock" :loading="isLoading">生成</Button>
-		</div>
-	</div>
-</template>
-
-<script>
-	import Mock from 'mockjs'
-	export default {
-		name: "BaseMock",
-		data() {
-			return {
-				isLoading: false,
-				acType: 0,
-                acId: '5ed79799-4e2d-471e-a484-deedb81a8ad7'
-			};
-		}, 
-		created() {},
-		methods: {
-			onMock() {
-				if (this.acId) {
-					this.isLoading = true
-					switch (this.acType) {
-						case 0:
-							this.doMockHomeWork(this.acId)
-							break
-						case 1:
-							this.doMockVote(this.acId)
-							break
-						case 2:
-							this.doMockQuestionnaire(this.acId)
-							break
-						case 3:
-							this.doMockEvaluation(this.acId)
-							break
-                        case 4:
-							this.doMockSelfLearning(this.acId)
-                            break	
-                        case 5:
-							this.doMockSelfLearning(this.acId)
-							break	
-						default:
-							break;
-					}
-				} else {
-					this.$Message.warning('请输入活动ID!')
-				}
-			},
-
-			/* 生成评测活动的学生模拟作答数据 */
-			async doMockEvaluation(acId) {
-				console.log(acId)
-				let classCodeArr = await this.getExamClass(acId)
-				let studentList = await this.getStudentList(classCodeArr)
-				let paper = await this.getExamPaper(acId)
-				console.log(console.log(paper))
-				let items = paper.item
-				let paperId = paper.id
-				let result = []
-				studentList.forEach(s => {
-					result.push({
-						id:paperId,
-						code:s.code,
-						examCode:acId,
-						status:1,
-						mark:0,
-						answers:[]
-					})
-				})
-				items.forEach((item,index) => {
-					result.forEach((i) => {
-						if(item.type === 'Complete'){
-							this.randomAnswer(item).forEach(j => {
-								i.answers.push({
-									num:i.answers.length,
-									group:index,
-									type:item.type,
-									ans:[j]
-								})
-							})
-						}else{
-							i.answers.push({
-								num:i.answers.length,
-								group:index,
-								type:item.type,
-								ans:this.randomAnswer(item)
-							})
-						}
-					})
-				})
-
-				 //保存模拟数据
-				this.$api.learnActivity.UpsertAllRecord(result).then(res => {
-					if (!res.error && res.result.data) {
-						this.$Message.success('保存成功!')
-						this.$emit('onSuccess')
-					} else {
-						this.$Message.error('保存失败!')
-					}
-					this.isLoading = false
-				})
-			},
-
-			/* 生成作业活动学生作答数据 */
-			async doMockHomeWork(acId) {
-				let result = []
-				// 拿到班级Code去换取学生名单
-				let classCodeArr = await this.getHomeWorkClass(acId)
-				let arr = await this.getStudentList(classCodeArr)
-				// 遍历随机赋值作答数据
-				arr.forEach(i => {
-					result.push({
-						id: acId,
-						code: i.code,
-						score: Mock.mock({"number|1-100": 100}).number,
-						content: [{
-							answers: Mock.mock('@cparagraph(2)'),
-							resource: []
-						}],
-						submit: true,
-						submitTime: new Date(Mock.mock('@datetime')).getTime()
-					})
-				})
-				// 保存模拟数据
-				this.$api.learnActivity.SaveHwRecords(result).then(res => {
-					if (!res.error && res.result.data) {
-						this.$Message.success('保存成功!')
-						this.$emit('onSuccess')
-					} else {
-						this.$Message.error('保存失败!')
-					}
-					this.isLoading = false
-				})
-			},
-
-			/* 生成自主学习学生作答数据 */
-			async doMockSelfLearning(acId) {
-                let result = []
-                let acInfo = null
-                if (this.acType == 4) {
-                    acInfo = await this.findOrderLearn()
-                    if (acInfo) {
-                        let taskes = await this.findTask()
-                        let classes = taskes.map((item) => {
-                            return item.code
-                        })
-                        let students = await this.getStudentList(classes)
-                        for (let item of students) {
-                            let rdItem = {
-                                id: this.acId,
-                                code: item.code,
-                                steps: []
-                            }
-                            let compSteps = this.$jsFn.getBtwRandom(0, (acInfo[0].steps.length + 1))
-                            for (let index = 0; index < compSteps; index++) {
-                                let aswItem = {
-                                    index: parseInt(index),
-									count:this.$jsFn.getBtwRandom(1,4),
-									score:this.$jsFn.getBtwRandom(50,100),
-                                    answer: []
-                                }
-                                acInfo[0].steps[index].item.forEach((question, i) => {
-                                    let stItem = {
-                                        index: i,
-                                        ans: this.randomAnswer(question),
-										//count: this.$jsFn.getBtwRandom(0,5)
-                                    }
-                                    aswItem.answer.push(stItem)
-                                })
-                                rdItem.steps.push(aswItem)
-                            }
-                            result.push(rdItem)
-                        }
-                        this.$api.learnActivity.upsertRecord(result).then(
-                            (res) => {
-                                if (!res.error && res.result.data) {
-                                    this.$Message.success('学习数据模拟成功!')
-                                } else {
-									this.$Message.error('学习数据模拟失败!')
-                                }
-                            },
-                            (err) => {
-								this.$Message.error('学习数据模拟失败!')
-                            }
-                        )
-                        
-                    }
-                } else if (this.acType == 5) {
-                    acInfo = await this.findUnit()
-                    let taskes = await this.findTask()
-                    let classes = taskes.map((item) => {
-                        return item.code
-                    })
-                    let students = await this.getStudentList(classes)
-                    for (let item of students) {
-                        let radom = this.$jsFn.getBtwRandom(0, 2)
-                        if (radom) {
-                            let rdItem = {
-                                id: this.acId,
-                                code: item.code,
-                                steps: []
-                            }
-                            let aswItem = {
-                                index: 0,
-                                answer: []
-                            }
-                            acInfo[0].item.forEach((question, i) => {
-                                let stItem = {
-                                    index: i,
-                                    ans: this.randomAnswer(question),
-                                    count: this.$jsFn.getBtwRandom(0, 5)
-                                }
-                                aswItem.answer.push(stItem)
-                            })
-                            rdItem.steps.push(aswItem)
-                            result.push(rdItem)
-                        }
-                    }
-                    console.log(result)
-                    this.$api.learnActivity.upsertRecord(result).then(
-                        (res) => {
-                            if (!res.error && res.result.data) {
-                                this.$Message.success('学习数据模拟成功!')
-                            } else {
-                                this.$Message.error('学习数据模拟失败!')
-                            }
-                        },
-                        (err) => {
-                            this.$Message.error('学习数据模拟失败!')
-                        }
-                    )
-                }
-                this.isLoading = false
-			},
-			
-			/* 生成投票活动学生作答数据 */
-			async doMockVote(acId) {
-				let result = []
-				// 拿到班级Code去换取学生名单
-				let voteItem = await this.getVoteInfo(acId)
-				let classCodeArr = voteItem.target.map(i => i.classroomCode)
-				let arr = await this.getStudentList(classCodeArr)
-				console.log(arr)
-				// 遍历随机赋值作答数据
-				arr.forEach(i => {
-					result.push({
-						id: acId,
-						code: i.id,
-						name:i.name,
-						classroom:{
-							name:i.classroomName , 
-							code:i.id
-						},
-						option:voteItem.option[Math.floor(Math.random() * voteItem.option.length)].code,
-						submit: true,
-						submitTime: new Date(Mock.mock('@datetime')).getTime()
-					})
-				})
-				console.log(result)
-				// 保存模拟数据
-				this.$api.learnActivity.SaveVoteRecords(result).then(res => {
-					if (!res.error && res) {
-						this.$Message.success('保存成功!')
-						this.$emit('onSuccess')
-					} else {
-						this.$Message.error('保存失败!')
-					}
-					this.isLoading = false
-				})
-			},
-			
-			/* 生成问卷活动学生作答数据 */
-			async doMockQuestionnaire(acId) {
-				let result = []
-				// 拿到班级Code去换取学生名单
-				let qnItem = await this.getQuestionnaireInfo(acId)
-				let classCodeArr = qnItem.target.map(i => i.classroomCode)
-				let arr = await this.getStudentList(classCodeArr)
-				console.log(arr)
-				// 遍历随机赋值作答数据
-				arr.forEach(i => {
-					result.push({
-						id: acId,
-						code: i.code,
-						classroom:{
-							name:qnItem.target.filter(j => j.classroomCode === i.id)[0].classroomName , 
-							code:i.id
-						},
-						submit: true,
-						submitTime: new Date(Mock.mock('@datetime')).getTime(),
-						answers:[]
-					})
-				})
-				
-				qnItem.items.forEach((item,index) => {
-					result.forEach((i) => {
-						i.answers.push({
-							order:i.answers.length,
-							answer:this.randomQnAnswer(item)
-						})
-					})
-				})
-				
-				// 保存模拟数据
-				this.$api.questionnaire.UpsertRecord(result).then(res => {
-					if (!res.error && res.result.data) {
-						this.$Message.success('保存成功!')
-						this.$emit('onSuccess')
-					} else {
-						this.$Message.error('保存失败!')
-					}
-					this.isLoading = false
-				})
-			},
-
-			/* 获取当前活动下的发布对象CODE */
-			async getHomeWorkClass(id) {
-				return new Promise((r, j) => {
-					this.$api.learnActivity.FindHomeWork({
-						id: id
-					}).then(res => {
-						if (!res.error && res.result.data) {
-							r(res.result.data[0].target.map(i => i.classroomCode))
-						} else {
-							j(500)
-						}
-					})
-				})
-			},
-			
-			/* 获取当前活动下的发布对象CODE */
-			async getVoteInfo(id) {
-				return new Promise((r, j) => {
-					this.$api.learnActivity.FindVote({
-						code:this.$store.state.userInfo.TEAMModelId,
-						id: id
-					}).then(async res => {
-						if (!res.error && res.votes) {
-							let privateSas = await this.$tools.getPrivateSas()
-							let schoolSas = await this.$tools.getSchoolSas()
-							let i = res.votes[0]
-							if (i.url) {
-								let sasString = i.code === this.$store.state.userInfo.TEAMModelId ? privateSas : schoolSas 
-								let jsonInfo = await this.$tools.getFile(i.url + sasString.sas)
-								let jsonData = JSON.parse(jsonInfo)
-								jsonData.id = i.id
-								jsonData.fileName = i.url.split('/')[i.url.split('/').length - 1].split('.json')[0]
-								r(jsonData)
-								console.log(jsonData)
-							}else{
-								r(i)
-							}
-						} else {
-							j(500)
-						}
-					})
-				})
-			},
-			
-			/* 获取当前活动下的发布对象CODE */
-			async getQuestionnaireInfo(id) {
-				return new Promise(async (r, j) => {
-					let privateSas = await this.$tools.getPrivateSas()
-					let schoolSas = await this.$tools.getSchoolSas()
-					this.$api.questionnaire.FindSurveys({
-						id: id
-					}).then(async res => {
-						if (!res.error && res.result.data) {
-								let i = res.result.data[0]
-								if (i.url) {
-									let sasString = i.code === this.$store.state.userInfo.TEAMModelId ? privateSas : schoolSas 
-									let jsonInfo = await this.$tools.getFile(i.url + sasString.sas)
-									let jsonData = JSON.parse(jsonInfo)
-									jsonData.id = i.id
-									jsonData.fileName = i.url.split('/')[i.url.split('/').length - 1].split('.json')[0]
-									r(jsonData)
-								}else{
-									r(i)
-								}
-						} else {
-							j(500)
-						}
-					})
-				})
-			},
-
-			/* 获取班级下面所有的学生清单 */
-			async getStudentList(classCodeList) {
-				console.log(classCodeList)
-				return new Promise((r, j) => {
-					this.$api.courseMgmt.getClassroomStudent({
-						classroomCode: classCodeList,
-						school_code: this.$store.state.userInfo.schoolCode
-					}).then(res => {
-						if (!res.error && res.classrooms) {
-							let list = []
-							res.classrooms.forEach(classroom => {
-								classroom.students.forEach(i => {
-									list.push({
-										id:i.id,
-										name:i.name,
-										no:i.no,
-										classroomName:classroom.name
-									})
-								})
-							})
-							if (this.acType === 3) {
-								r(list)
-							} else {
-								r(list)
-							}
-						} else {
-							j(500)
-						}
-					})
-				})
-			},
-            //查询学习任务
-            async findTask() {
-                return new Promise((r, j) => {
-                    this.$api.learnActivity.findTask({
-                        id: this.acId
-                    }).then(
-                        (res) => {
-                            if (!res.error && res.result.data) {
-								r(res.result.data)
-                            } else {
-                                j(500)
-                            }
-                        },
-                        (err) => {
-                            j(500)
-                        }
-                    )
-                })
-            },
-			/**
-             * 查询编序式教材列表
-             * */
-            async findOrderLearn() {
-                return new Promise((r, j) => {
-                    let requestData = {
-                        id: this.acId
-                    }
-                    this.$api.learnActivity.FindOrderLearn(requestData).then(
-                        res => {
-                            if (!res.error && res.result.data) {
-                                r(res.result.data)
-                            } else {
-                                j(500)
-                            }
-                        },
-                        err => {
-							j(500)
-                        }
-                    )
-                })
-            },
-            /**
-             * 查询最小单元列表
-             * */
-            async findUnit() {
-                return new Promise((r, j) => {
-                    let requestData = {
-                        id: this.acId
-                    }
-                    this.$api.learnActivity.FindUnit(requestData).then(
-                        res => {
-                            if (!res.error && res.result.data) {
-                                r(res.result.data)
-                            } else {
-                                j(500)
-                            }
-                        },
-                        err => {
-							j(500)
-                        }
-                    )
-                })
-            },
-			/* 获取评测施测班级 */
-			getExamClass(id) {
-				return new Promise((r, j) => {
-					this.$api.learnActivity.FindExamInfo({
-						id: id
-					}).then(res => {
-						console.log('学生班级')
-						console.log(res.result.data)
-						if (!res.error && res.result.data) {
-							r(res.result.data[0].target)
-						} else {
-							j(500)
-						}
-					})
-				})
-			},
-			
-			/* 获取评测试卷信息 */
-			getExamPaper(id) {
-				return new Promise((r, j) => {
-					this.$api.learnActivity.FindExamPaper({
-						code: id
-					}).then(res => {
-						if (!res.error && res.result.data) {
-							r(res.result.data[1])
-						} else {
-							j(500)
-						}
-					})
-				})
-			},
-			
-			/* 根据题型生成随机答案 */
-            randomAnswer(item) {
-				switch (item.type) {
-					case 'Single':
-						return [item.option[Math.floor(Math.random() * item.option.length)].code]
-						break;
-					case 'Multiple':
-						return [item.option[Math.floor(Math.random() * item.option.length)].code]
-						break;
-					case 'Judge':
-						let arr = ['A','B'] 
-						return [arr[Math.floor(Math.random() * 2)]]
-						break;
-					case 'Complete':
-						let ans = item.answer.map(i => i = Mock.mock('@cparagraph(2)'))
-						return ans
-						break;	
-					default:
-						return [Mock.mock('@cparagraph(2)')]
-						break;
-				}
-			},
-			/* 根据题型生成随机答案 */
-			randomQnAnswer(item) {
-				switch (item.type) {
-					case 'Single':
-						return [item.options[Math.floor(Math.random() * item.options.length)].code]
-						break;
-					case 'Multiple':
-						return [item.options[Math.floor(Math.random() * item.options.length)].code]
-						break;
-					case 'Judge':
-						let arr = ['A','B'] 
-						return [arr[Math.floor(Math.random() * 2)]]
-						break;
-					default:
-						return [Mock.mock('@cparagraph(2)')]
-						break;
-				}
-			},
-		},
-		mounted() {}
-	};
-</script>

+ 16 - 10
TEAMModelOS/ClientApp/src/common/BaseMyCanvas.vue

@@ -7,12 +7,12 @@
 				<Poptip trigger="click">
 					<div class="flex-center">
 						<Icon type="md-create" />
-						<span>绘制</span>
+						<span>{{ vm.$t('utils.draw') }}</span>
 					</div>
 					<div slot="content" class="textBox">
-						 <p class="text-tools-title">画笔粗细 <span style="font-weight: bold;color: #0086E6;margin-left: 15px;font-size: 18px;">{{ options.textSize }}</span> </p>
+						 <p class="text-tools-title">{{ vm.$t('utils.width') }} <span style="font-weight: bold;color: #0086E6;margin-left: 15px;font-size: 18px;">{{ options.textSize }}</span> </p>
 						 <Slider v-model="options.writeWidth"></Slider>
-						 <p class="text-tools-title">画笔颜色</p>
+						 <p class="text-tools-title">{{ vm.$t('utils.color') }}</p>
 						 <ColorPicker v-model="options.writeColor" />
 					</div>
 				</Poptip>
@@ -21,31 +21,31 @@
 				<Poptip trigger="click">
 					<div class="flex-center">
 						<Icon type="md-text" />
-						<span>文本输入</span>
+						<span>{{ vm.$t('utils.text') }}</span>
 					</div>
 					<div slot="content" class="textBox">
-						 <p class="text-tools-title">字体大小 <span style="font-weight: bold;color: #0086E6;margin-left: 15px;font-size: 18px;">{{ options.textSize }}</span> </p>
+						 <p class="text-tools-title">{{ vm.$t('utils.fontSize') }} <span style="font-weight: bold;color: #0086E6;margin-left: 15px;font-size: 18px;">{{ options.textSize }}</span> </p>
 						 <Slider v-model="options.textSize"></Slider>
-						 <p class="text-tools-title">字体颜色</p>
+						 <p class="text-tools-title">{{ vm.$t('utils.fontColor') }}</p>
 						 <ColorPicker v-model="options.textColor" />
 					</div>
 				</Poptip>
 			</span>
 			<span class="canvas-tools-item" @click="canvasClear()">
 				<Icon type="md-refresh" />
-				<span>清屏</span>
+				<span>{{ vm.$t('utils.clear') }}</span>
 			</span>
 			<span class="canvas-tools-item" @click="undo()">
 				<Icon type="md-undo" />
-				<span>撤销</span>
+				<span>{{ vm.$t('utils.undo') }}</span>
 			</span>
 			<span class="canvas-tools-item" @click="closeModal()">
 				<Icon type="md-close" />
-				<span>关闭</span>
+				<span>{{ vm.$t('utils.close') }}</span>
 			</span>
 			<span class="canvas-tools-item" @click="downloadSignImg()" style="border-radius:  0 15px 0 0 ;">
 				<Icon type="md-cloud-download" />
-				<span>保存</span>
+				<span>{{ vm.$t('utils.save') }}</span>
 			</span>
 		</div>
 	</div>
@@ -57,6 +57,12 @@
 			BaseCanvas
 		},
 		props: {
+			vm:{
+				type:Object,
+				default:() => {
+					return {}
+				}
+			},
 			isStudent: {
 				type: Boolean,
 				default: false

+ 3 - 3
TEAMModelOS/ClientApp/src/common/BaseNotification.vue

@@ -1,8 +1,8 @@
 <template>
 	<div class="base-notification">
-		<Poptip title="新通知" class="dark-iview-poptip">
+		<Poptip :title="$t('utils.newNotice')" class="dark-iview-poptip">
 			<Icon type="md-notifications" />
-			<div slot="content" class="notice-wrap">
+			<!-- <div slot="content" class="notice-wrap">
 				<div class="notice-item">
 					<p class="item-name">青城山学校</p>
 					<p class="item-content">活动[2020下学期国文期末考]达成率已达100%</p>
@@ -18,7 +18,7 @@
 					<p class="item-content">活动[2020下学期国文期末考]达成率已达100%</p>
 					<span class="item-time">2020-08-14 18:22</span>
 				</div>
-			</div>
+			</div> -->
 		</Poptip>
 	</div>
 </template>

+ 3 - 3
TEAMModelOS/ClientApp/src/common/BaseSelectSchool.vue

@@ -1,6 +1,6 @@
 <template>
 	<div class="base-school-select">
-		<div v-if="!joinSchools || !joinSchools.length">暂未加入学校</div>
+		<div v-if="!joinSchools || !joinSchools.length">{{ $t('utils.noJoinSchool') }}</div>
 		<Dropdown @on-click="onSchoolSelect" v-else>
 			<img class="school-logo" :src="curSchool.logo || defaultLogo" />
 			<a href="javascript:void(0)" :class="['base-user-post', joinSchools && joinSchools.length === 1 ? 'single-school' : '']">
@@ -56,7 +56,7 @@
 				this.curSchool = user.defaultschool ? joinSchools.filter(i => i.schoolId === user.defaultschool)[0] : joinSchools[0]
 				this.$store.commit('setSchoolCode', this.curSchool.schoolId)
 			} else {
-				this.$Message.warning('用户暂无学校列表数据')
+				this.$Message.warning(this.$t('utils.noShoolTip'))
 			}
 		},
 		methods: {
@@ -97,7 +97,7 @@
 							}
 						},
 						(err) => {
-							this.$Message.error("数据获取失败!")
+							this.$Message.error(this.$t('utils.getDataFail'))
 						}
 					)
 				})

+ 18 - 18
TEAMModelOS/ClientApp/src/common/BaseUserPoptip.vue

@@ -10,8 +10,8 @@
 						<Icon type="ios-arrow-down"></Icon>
 					</a>
 					<DropdownMenu slot="list">
-						<DropdownItem v-if="curRole != 'teacher' && curRole != 'admin'" name="teacher">教师</DropdownItem>
-						<DropdownItem v-if="curRole != 'student'" name="student">學生</DropdownItem>
+						<DropdownItem v-if="curRole != 'teacher' && curRole != 'admin'" name="teacher">{{ $t('utils.teacher') }}</DropdownItem>
+						<DropdownItem v-if="curRole != 'student'" name="student">{{ $t('utils.student') }}</DropdownItem>
 						<!-- <DropdownItem  name="student">學生</DropdownItem> -->
 					</DropdownMenu>
 				</Dropdown>
@@ -28,26 +28,26 @@
 						<span class="user-info-username">{{ userInfo.username }}</span>
 						<span class="user-info-account">{{ user.id }}</span>
 						<span class="user-info-account">{{ curRole }}</span>
-						<span class="user-info-btn">账号管理</span>
+						<span class="user-info-btn">{{ $t('utils.accountManage') }}</span>
 					</div>
 					<div class="user-nums">
 						<div class="user-nums-item">
 							<span>{{ userInfo.courseNum }}</span>
-							<span>任教课程数</span>
+							<span>{{ $t('utils.courseNum') }}</span>
 						</div>
 						<div class="user-nums-item">
 							<span>{{ userInfo.activityNum }}</span>
-							<span>发布活动数</span>
+							<span>{{ $t('utils.activityNum') }}</span>
 						</div>
 						<div class="user-nums-item">
 							<span>{{ userInfo.classNum }}</span>
-							<span>任教班级数</span>
+							<span>{{ $t('utils.classNum') }}</span>
 						</div>
 					</div>
 					<div class="user-storage">
 						<p :style="{color: sizeInfo.total > $GLOBAL.PRIVATE_SPACE ? '#ff2929' : '#a5a5a5'}">
-							<span v-if="sizeInfo.total > $GLOBAL.PRIVATE_SPACE">(已满)</span>
-							个人空间状态
+							<span v-if="sizeInfo.total > $GLOBAL.PRIVATE_SPACE">({{ $t('utils.full') }})</span>
+							{{ $t('utils.spaceStatus') }}
 							{{ getSizeVal(sizeInfo.total) }} / {{ getSizeVal($GLOBAL.PRIVATE_SPACE) }}
 						</p>
                         <div class="user-storage-distribution">
@@ -61,16 +61,16 @@
                             <span class="storage-data" :style='{ width: getPercent(sizeInfo.data) }'></span>
                         </div>
 						<p class="user-storage-text">
-							<span v-if="sizeInfo.res != 0" class="text-res">教材:{{ getSizeVal(sizeInfo.res) }}</span>
-							<span v-if="sizeInfo.image != 0" class="text-image">图片:{{ getSizeVal(sizeInfo.image) }}</span>
-							<span v-if="sizeInfo.video != 0" class="text-video">视频:{{ getSizeVal(sizeInfo.video) }}</span>
-							<span v-if="sizeInfo.audio != 0" class="text-audio">音频:{{ getSizeVal(sizeInfo.audio) }}</span>
-							<span v-if="sizeInfo.doc != 0" class="text-doc">文档:{{ getSizeVal(sizeInfo.doc) }}</span>
-							<span v-if="sizeInfo.data != 0" class="text-data">题库:{{ getSizeVal(sizeInfo.data) }}</span>
-							<span v-if="sizeInfo.other != 0" class="text-other">其他内容:{{ getSizeVal(sizeInfo.other) }}</span>
+							<span v-if="sizeInfo.res != 0" class="text-res">{{ $t('utils.res') }}:{{ getSizeVal(sizeInfo.res) }}</span>
+							<span v-if="sizeInfo.image != 0" class="text-image">{{ $t('utils.img') }}:{{ getSizeVal(sizeInfo.image) }}</span>
+							<span v-if="sizeInfo.video != 0" class="text-video">{{ $t('utils.video') }}:{{ getSizeVal(sizeInfo.video) }}</span>
+							<span v-if="sizeInfo.audio != 0" class="text-audio">{{ $t('utils.audio') }}:{{ getSizeVal(sizeInfo.audio) }}</span>
+							<span v-if="sizeInfo.doc != 0" class="text-doc">{{ $t('utils.doc') }}:{{ getSizeVal(sizeInfo.doc) }}</span>
+							<span v-if="sizeInfo.data != 0" class="text-data">{{ $t('utils.bank') }}:{{ getSizeVal(sizeInfo.data) }}</span>
+							<span v-if="sizeInfo.other != 0" class="text-other">{{ $t('utils.other') }}:{{ getSizeVal(sizeInfo.other) }}</span>
 						</p>
 					</div>
-					<div class="btn-logout" @click="onQuit">登出</div>
+					<div class="btn-logout" @click="onQuit">{{ $t('utils.logout') }}</div>
 				</div>
 			</Poptip>
 		</div>
@@ -127,7 +127,7 @@
                         this.sizeInfo = res
                     },
                     err => {
-                        this.$Message.error('空间计算异常')
+                        this.$Message.error(this.$t('utils.caclErrorL'))
                     }
                 )
 			},
@@ -169,7 +169,7 @@
 			},
 			getRoleName() {
 				return val => {
-					return val === 'student' ? '学生' : '教师'
+					return val === 'student' ? this.$t('utils.student') : this.$t('utils.teacher')
 				}
 			}
 		},

+ 0 - 41
TEAMModelOS/ClientApp/src/common/BaseVideoPlayer.vue

@@ -1,41 +0,0 @@
-<template>
-	<div class="audio-container">
-		<p style="margin-left: 15px;margin-bottom: 10px;">{{ videoName }}</p>
-		<video :src="videoSrc" id="video" controls="controls" width="100%"></video>
-	</div>
-</template>
-
-<script>
-	export default {
-		name: 'audioPlayer',
-		props: {
-			videoSrc: {
-				type: String,
-				default: ''
-			},
-			videoName: {
-				type: String,
-				default: ''
-			}
-		},
-		data() {
-			return {
-				audioList: []
-			}
-		},
-		created() {
-			// console.log(this.videoSrc);
-		},
-		methods: {
-			onCloseAudio() {
-				document.getElementById('video').pause()
-			},
-			onPlayAudio() {
-				document.getElementById('video').play()
-			}
-		}
-	}
-</script>
-<style>
-
-</style>

+ 2 - 3
TEAMModelOS/ClientApp/src/common/EmptyData.vue

@@ -20,9 +20,8 @@
 		  },
 		  textContent: {
 			type: String,
-			default: () => {
-				// return this.$t('evaluation.newExercise.newSchoolItem')
-				return '暂无数据'
+			default: function (){
+				return this.$t('evaluation.noData')
 			}
 		  }
 		},

+ 5 - 6
TEAMModelOS/ClientApp/src/common/ImportExcel.vue

@@ -11,9 +11,9 @@
                     <p>{{(row.password == '' || row.password == null)? '— —' : row.password.value+''}}</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="row.seatRepeat? 'account-error-tips':''">{{row.seatRepeat ? "错误:座位号重复":"" }}</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)?"":$t('system.compt.acRep') }}</p>
+                    <p :class="(row.classroomCode == '' || row.classroomCode == null) ? 'account-warning-tips':''">{{(row.classroomCode == '' || row.classroomCode == null) ? $t('system.compt.classErr'):"" }}</p>
+                    <p :class="row.seatRepeat? 'account-error-tips':''">{{row.seatRepeat ? $t('system.compt.setErr'):"" }}</p>
                 </template>
             </Table>
         </div>
@@ -78,7 +78,7 @@
                     this.showProgress = true
                 }
                 reader.onerror = e => {
-                    this.$Message.error('文件读取失败!')
+                    this.$Message.error(this.$t('system.compt.fileReadErr'))
                 }
                 reader.onload = e => {
                     const data = e.target.result
@@ -100,12 +100,11 @@
                     if (flag) {
                         // 处理表格导入数据类型
                         this.tableData = [...results]
-                        //this.$Message.info('文件读取成功')
                         this.tableLoading = false
                         this.$emit('getTableData', this.tableData)
                     } else {
                         this.$Message.error({
-                            content: '导入数据没有' + column + ',请完善表格数据再导入',
+                            content: this.$t('system.compt.tbColErr1') + column + this.$t('system.compt.tbColErr2'),
                             duration: 4
                         })
                         this.tableLoading = false

+ 0 - 408
TEAMModelOS/ClientApp/src/common/NewUploadFile.vue

@@ -1,408 +0,0 @@
-<template>
-    <div class="upload-file-box">
-        <Upload type="drag" action="" :show-upload-list="false" multiple :before-upload="customUpload" class="upload-wrap">
-            <Icon class="upload-icon" custom="iconfont icon-upload" v-show="!uploadedList.length" />
-            <p class="upload-text" :style="{marginTop: uploadedList.length ? '25px':'0px'}">
-                <Icon size="24" style="font-size: 22px;vertical-align: baseline;margin-right: 5px;" custom="iconfont icon-upload" v-show="uploadedList.length" />
-                {{$t('teachContent.uploadText')}}
-            </p>
-            <p class="upload-text" style="font-size:12px;">* 上传相同名字的文件会自动覆盖</p>
-            <p class="upload-text" :style="{fontSize:'12px',marginBottom: uploadedList.length ? '25px':'50px'}">
-                * 勾选
-                <Icon custom="iconfont icon-convert" size="12"  class="is-parse-htex"/>
-                支持PPTX文档转换成HTEX教材
-            </p>
-        </Upload>
-        <div class="upload-file-box">
-            <div class="upload-file-item" v-for="(item,index) in uploadedList" :key="index">
-                <div class="upload-item-left">
-                    <p class="upload-file-name">
-                        <span v-if="item.type == 'res'" class="file-type-tag" style="color: #1FFCC5;border-color: #1FFCC5">教材</span>
-                        <span v-else-if="item.type == 'image'" class="file-type-tag" style="color: #45C84A;border-color: #45C84A">图片</span>
-                        <span v-else-if="item.type == 'video'" class="file-type-tag" style="color: #8E2BDD;border-color: #8E2BDD">视频</span>
-                        <span v-else-if="item.type == 'audio'" class="file-type-tag" style="color: #E1027B;border-color: #E1027B">音频</span>
-                        <span v-else-if="item.type == 'doc'" class="file-type-tag" style="color: #03C0C2;border-color: #03C0C2">{{item.isParse ? '转换':'文档'}}</span>
-                        <span v-else class="file-type-tag" style="color: #E87B22; border-color: #E87B22">其他</span>
-                        <span>{{item.name}}</span>
-                    </p>
-                    <span class="upload-info-wrap" style="color:white;">
-                        {{parseInt(item.loadedBytes * 100 / item.size)+'%'}}
-                    </span>
-                    <span class="upload-info-wrap">
-                        {{getSizeByBytes(item.loadedBytes)+'/'+getSizeByBytes(item.size)}}
-                    </span>
-                    <span v-if="item.extension == 'PPTX'" class="upload-info-wrap parse-label" @click="item.isParse = !item.isParse" :style="{color:item.isParse ? '#1cc0f3':'#808080'}">
-                        <Icon class="is-parse-htex" size="12" custom="iconfont icon-convert" />
-                        转成HTEX教材
-                    </span>
-                    <Progress style="top:-10px;" v-if="item.status == 0" :percent="item.loadedBytes * 100 / item.size" status="active" stroke-color="#1CC0F3" :stroke-width="2" hide-info />
-                </div>
-                <div class="upload-item-right">
-                    <Icon type="ios-close" class="delete-btn" color="red" size="30" style="float:right;" @click="deleteFile(index)" />
-                </div>
-            </div>
-        </div>
-    </div>
-</template>
-<script>
-import '@/icons/svg/loading3.svg';
-import BlobTool from '@/utils/blobTool.js';
-export default {
-    data() {
-        return {
-            uploadedList: [],
-            containerClient: null,
-            routerScope: ''
-        }
-    },
-    props: {
-        //默认文件列表
-        defaultFileList: {
-            default: () => {
-                return []
-            },
-            type: Array
-        },
-        //文件路径
-        path: {
-            default: '',
-            type: String,
-            required: true
-        },
-        //授权信息
-        sasString: {
-            default: '',
-            type: String,
-            required: true
-        },
-        //blob链接
-        urlString: {
-            default: '',
-            type: String,
-            required: true
-        },
-        //容器名称
-        containerName: {
-            default: '',
-            type: String,
-            required: true
-        },
-        //文件大小限制
-        maxSize: {
-            default: 2 * 1024 * 1024 * 1024,
-            type: Number
-        },
-        //文件格式限制
-        format: {
-            default: () => {
-                return []
-            },
-            type: Array
-        }
-    },
-    methods: {
-        //删除文件
-        deleteFile(index) {
-            this.containerClient.deleteBlob(this.uploadedList[index].blob).then(
-                res => {
-                    //删除缩略图和封面
-                    if (this.uploadedList[index].type == 'image') {
-                        let thum = this.uploadedList[index].blob.replace('/image/', '/thum/')
-                        this.containerClient.deleteBlob(thum)
-                    } else if (this.uploadedList[index].type == 'video') {
-                        let thum = this.uploadedList[index].blob.replace('/video/', '/thum/')
-                        thum = thum.slice(0, thum.lastIndexOf('.')) + '.png'
-                        this.containerClient.deleteBlob(thum)
-                    }
-                    this.$emit('deleteFile', this._.cloneDeep(this.uploadedList[index]))
-                    this.uploadedList.splice(index, 1)
-                    this.$Message.success('删除成功!')
-                },
-                err => {
-                    this.$Message.error('删除失败!')
-                }
-            )
-        },
-        getFileType(fileName) {
-            let extension = fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length)
-            extension = extension.toUpperCase()
-            for (let key in this.$GLOBAL.CONTENT_TYPES) {
-                if (this.$GLOBAL.CONTENT_TYPES[key].indexOf(extension) != -1) {
-                    return key
-                }
-            }
-            return 'other'
-        },
-        getSizeByBytes(bytes) {
-            return bytes / 1024 < 1024 ? (bytes / 1024).toFixed(1) + 'KB' : bytes / 1024 / 1024 < 1024 ? (bytes / 1024 / 1024).toFixed(1) + 'M' : (bytes / 1024 / 1024 / 1024).toFixed(1) + 'G'
-        },
-        async customUpload(file) {
-            if (file.size > this.maxSize) {
-                this.$Message.error({
-                    content: "文件大小超出限制",
-                    duration: 3
-                })
-                return false
-            }
-
-            let extension = file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length)
-            if (this.format.length > 0 && this.format.indexOf(extension) == -1) {
-                this.$Message.error({
-                    content: "文件类型不支持",
-                    duration: 3
-                })
-                return false
-            }
-
-            let fileType = this.getFileType(file.name)
-            //上传文件
-            let fileInfo = {
-                url: this.urlString + '/' + this.containerName + '/' + fileType + '/' + file.name,
-                name: file.name,
-                size: file.size,
-                loadedBytes: 0,
-                progress: 0,
-                status: 0,
-                type: fileType,
-                file: file,
-                extension: extension.toUpperCase(),
-                isParse: false
-            }
-            this.uploadedList.push(fileInfo)
-            let _this = this
-            let index = this.uploadedList.length - 1
-            // this.containerClient.upload(file, fileType, {
-            //     onProgress: function (e) {
-            //         _this.uploadedList[index].loadedBytes = e.loadedBytes
-            //         _this.uploadedList[index].progress = parseInt(e.loadedBytes * 100 / file.size)
-            //     }
-            // }).then(
-            //     res => {
-            //         this.uploadedList[index].status = 1
-            //         this.uploadedList[index].blob = res.blob
-            //         extension = extension.toUpperCase()
-            //         if (res.type == 'image') {
-            //             this.uploadThum(file)
-            //             this.$emit('successData', res)
-            //         } else if (res.type == 'video') {
-            //             this.uploadPoater(res)
-            //             this.$emit('successData', res)
-            //         } else if (extension == 'PPTX') {
-            //             this.$Modal.confirm({
-            //                 title: '文件解析',
-            //                 okText: '是',
-            //                 cancelText: '否',
-            //                 content: `<p>是否将<strong style='color:red;'>${file.name}</strong>转成HTEX文件?</p>`,
-            //                 onOk: () => {
-            //                     this.$emit('parsing')
-            //                     this.$emit('successData', res)
-            //                     let delBlob = res.blob
-            //                     this.$api.teachContent.ParseDoc({
-            //                         file: res.url,
-            //                         scope: this.routerScope
-            //                     }).then(
-            //                         parseRes => {
-            //                             this.containerClient.deleteBlob(delBlob)
-            //                             res.blob = `/res/${res.name}/index.json`
-            //                             res.extension = 'HTEX'
-            //                             res.name = res.name.replace('pptx', 'HTEX').replace('PPTX', 'HTEX')
-            //                             res.type = 'res'
-
-            //                             this.$emit('parseComplete')
-            //                             this.$Message.success('解析成功')
-            //                         },
-            //                         parseErr => {
-            //                             this.$Message.error('解析失败')
-            //                         }
-            //                     )
-            //                 },
-            //                 onCancel: () => {
-            //                     this.$emit('successData', res)
-            //                 }
-            //             })
-            //         } else if (extension == 'HTEX') {
-            //             let delBlob = res.blob
-            //             this.$emit('parsing')
-            //             res.blob = `/res/${res.name}/index.json`
-            //             this.$emit('successData', res)
-            //             this.$api.teachContent.ParseDoc({
-            //                 file: res.url,
-            //                 scope: this.routerScope
-            //             }).then(
-            //                 parseRes => {
-            //                     this.containerClient.deleteBlob(delBlob)
-            //                 },
-            //                 parseErr => {
-            //                     this.$Message.error('上传失败')
-            //                     this.containerClient.deleteBlob(delBlob)
-            //                 }
-            //             ).finally(() => {
-            //                 this.$emit('parseComplete')
-            //             })
-            //         }
-            //     },
-            //     err => {
-            //         this.uploadedList[index].status = 2
-            //         if (err.spaceError) {
-            //             this.$Message.error(err.spaceError)
-            //         } else {
-            //             this.$Message.error("上传失败")
-            //         }
-            //     }
-            // )
-            return false
-        },
-        //处理图片缩略图
-        async uploadThum(file) {
-            let dataUrl = await this.$jsFn.fileToURL(file)
-            dataUrl = await this.$jsFn.compressImgByUrl(dataUrl, file.name, 0.1)
-            let f = this.$jsFn.dataURLtoFile(dataUrl, file.name)
-            this.containerClient.upload(f, 'thum').then(
-                res => {
-                    console.log('压缩图上传成功')
-                },
-                err => {
-                    console.log('压缩图上传失败')
-                }
-            )
-        },
-        //处理视频封面
-        async uploadPoater(file) {
-            let n = file.name.substring(0, file.name.lastIndexOf('.'))
-            console.log(n)
-            console.log('视频蜂蜜昂')
-            let dataUrl = await this.$jsFn.createVideoPoster(file.url + this.sasString, file.name, 0.1)
-            let f = this.$jsFn.dataURLtoFile(dataUrl, n + '.png')
-            console.log(f)
-            this.containerClient.upload(f, 'thum').then(
-                res => {
-                    console.log('视频封面上传成功')
-                },
-                err => {
-                    console.log('视频封面上传失败')
-                }
-            )
-        }
-    },
-    created() {
-        let route = this.$route
-        if (route.name == 'personalcontent') {
-            this.routerScope = 'private'
-        } else {
-            this.routerScope = 'school'
-        }
-    },
-    watch: {
-        urlString: {
-            handler(v, o) {
-                if (this.urlString && this.containerName && this.sasString) {
-                    let scope = ''
-                    if (this.containerName == this.$store.state.userInfo.TEAMModelId) {
-                        scope = 'private'
-                    } else if (this.containerName == this.$store.state.userInfo.schoolCode) {
-                        scope = 'school'
-                    }
-                    //初始化Blob
-                    this.containerClient = new BlobTool(this.urlString, this.containerName, this.sasString, scope)
-                }
-            }
-        },
-        containerName: {
-            handler(v, o) {
-                if (this.urlString && this.containerName && this.sasString) {
-                    let scope = ''
-                    if (this.containerName == this.$store.state.userInfo.TEAMModelId) {
-                        scope = 'private'
-                    } else if (this.containerName == this.$store.state.userInfo.schoolCode) {
-                        scope = 'school'
-                    }
-                    //初始化Blob
-                    this.containerClient = new BlobTool(this.urlString, this.containerName, this.sasString, scope)
-                }
-            }
-        },
-        sasString: {
-            handler(v, o) {
-                if (this.urlString && this.containerName && this.sasString) {
-                    let scope = ''
-                    if (this.containerName == this.$store.state.userInfo.TEAMModelId) {
-                        scope = 'private'
-                    } else if (this.containerName == this.$store.state.userInfo.schoolCode) {
-                        scope = 'school'
-                    }
-                    //初始化Blob
-                    this.containerClient = new BlobTool(this.urlString, this.containerName, this.sasString, scope)
-                }
-            }
-        }
-    }
-}
-
-</script>
-<style scoped>
-.upload-text {
-    margin: 10px 0px;
-    font-size: 24px;
-}
-.upload-icon {
-    font-size: 50px;
-    margin-top: 60px;
-}
-.upload-file-item {
-    color: #909090;
-    margin-top: 5px;
-    padding: 5px 2px 0px 5px;
-    display: flex;
-}
-.upload-item-left {
-    width: calc(100% - 25px);
-}
-.upload-item-right {
-    width: 25px;
-}
-.upload-info-wrap {
-    float: right;
-    margin-left: 10px;
-    vertical-align: middle;
-    /* color: white; */
-    line-height: 30px;
-}
-
-.upload-file-item:hover {
-    /* color: white; */
-    /* background: #585858; */
-    border-radius: 5px;
-}
-
-.upload-file-item:hover .delete-btn {
-    display: inline-block;
-}
-.upload-loading-icon {
-    vertical-align: middle;
-}
-.upload-file-name {
-    display: inline-block;
-    color: #eeeeee;
-    line-height: 30px;
-}
-
-.delete-btn {
-    display: none;
-}
-.file-type-tag {
-    border: 1px solid;
-    /*border-color:white;*/
-    border-radius: 2px;
-    padding: 0px 4px;
-    margin-right: 5px;
-    font-size: 12px;
-}
-.parse-label {
-    cursor: pointer;
-    font-size: 12px;
-    user-select: none;
-}
-.is-parse-htex {
-    vertical-align: baseline;
-}
-</style>

+ 2 - 2
TEAMModelOS/ClientApp/src/common/UploadFile.vue

@@ -236,7 +236,7 @@
                 let url = file.name
                 if (file.size > this.maxSize) {
                     this.$Message.error({
-                        content: "文件大小超出限制",
+                        content: this.$t('system.compt.sizeErr'),
                         duration: 3
                     })
                     return false
@@ -245,7 +245,7 @@
                 let extension = file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length)
                 if (this.format.length > 0 && this.format.indexOf(extension) == -1) {
                     this.$Message.error({
-                        content: "文件类型不支持",
+                        content: this.$t('system.compt.typeErr'),
                         duration: 3
                     })
                     return false

+ 1 - 1
TEAMModelOS/ClientApp/src/common/VideoPlayer2.vue

@@ -60,7 +60,7 @@
                         "font-size": "16px",
                     },
                     text: function (marker) {
-                        return "课件 " + marker.text;
+                        return this.$t('system.compt.cusWare') + marker.text;
                     },
                 },
                 markerTip: {

+ 1 - 1
TEAMModelOS/ClientApp/src/components/evaluation/ExerciseList.less

@@ -316,7 +316,7 @@
       }
     }
     span {
-      &:nth-child(5) {
+      &:nth-child(4) {
         border-right-width: 0;
       }
     }

+ 1 - 1
TEAMModelOS/ClientApp/src/components/evaluation/ExerciseList.vue

@@ -87,7 +87,7 @@
 					<span class="item-tools-info">{{$t('evaluation.filter.diff')}}:{{ exersicesDiff[item.level - 1] }}</span>
 					<span class="item-tools-info">{{$t('evaluation.filter.level')}}:{{ exersicesField[item.field - 1] }}</span>
 					<span class="item-tools-info">{{$t('evaluation.filter.useCount')}}:{{ item.usageCount || 0 }} 次</span>
-					<span class="item-tools-info">{{$t('evaluation.updateTime')}}:{{ $tools.formatTime(item.createTime)  || 0 }} </span>
+					<!-- <span class="item-tools-info">{{$t('evaluation.updateTime')}}:{{ $tools.formatTime(item.createTime)  || 0 }} </span> -->
 					<Button type="info" v-if="!isAnalysis" :style="{backgroundColor:selectList.map(i => i.id).indexOf(item.id) > -1 ? '#bbbbbb' : '#2db7f5'}"
 					 @click.stop="onSelectItem(item,index)">{{ selectList.map(i => i.id).indexOf(item.id) > -1 ? $t('evaluation.remove') : $t('evaluation.choose')}}</Button>
 				</div>

+ 3 - 3
TEAMModelOS/ClientApp/src/components/questionnaire/BaseJudge.vue

@@ -1,11 +1,11 @@
 <template>
 	<div class="question-single">
 		<div class="exersices-content">
-			<IconText :text="'题目'" :color="'#2d8cf0'" :icon="'ios-create'" style="margin-bottom:15px;"></IconText>
+			<IconText :text="$t('survey.question')" :color="'#2d8cf0'" :icon="'ios-create'" style="margin-bottom:15px;"></IconText>
 			<div ref="singleEditor" style="text-align:left"></div>
 		</div>
 		<div class="question-option" style="margin-top:20px">
-			<IconText :text="'判断选项'" :color="'#FF871C'" :icon="'md-reorder'"></IconText>
+			<IconText :text="$t('survey.judgeOption')" :color="'#FF871C'" :icon="'md-reorder'"></IconText>
 			<div v-if="options.length">
 				<div v-for="(item,index) in options" :key="index" :ref="'optionBox' + index" class="option-editor-wrap" style="margin-top:10px;display:flex">
 					<span class="fl-center option-order">{{String.fromCharCode(64 + parseInt(index+1))}}</span>
@@ -137,7 +137,7 @@
 						this.refreshOrder()
 					})
 				} else {
-					this.$Message.warning('最多只有9个选项!')
+					this.$Message.warning(this.$t('survey.optionMaxTip'))
 				}
 			},
 			

+ 1 - 1
TEAMModelOS/ClientApp/src/components/questionnaire/BaseProgress.vue

@@ -33,7 +33,7 @@
 					tooltip: {
 						trigger: 'item',
 						formatter: function(params) {
-							return `问卷完成度:${ (((that.total - that.noAnswerdCount) / that.total) * 100).toFixed(2) }%`
+							return `${ that.$t('survey.questionaire.progress') }:${ (((that.total - that.noAnswerdCount) / that.total) * 100).toFixed(2) }%`
 						}
 					},
 					angleAxis: {

+ 0 - 12
TEAMModelOS/ClientApp/src/components/selflearn/ExerciseList.vue

@@ -165,18 +165,6 @@
             </div>
         </div>
 
-        <!-- 音频播放弹窗 -->
-        <Modal v-model="playAudioModal" width="400" footer-hide @on-visible-change="onAudioModalChange">
-            <div class="modal-header" slot="header">音频播放</div>
-            <BaseAudioPlayer :audioSrc="curAudioSrc" :audioName="curAudioName" ref="audioPlayer"></BaseAudioPlayer>
-        </Modal>
-
-        <!-- 视频播放弹窗 -->
-        <Modal v-model="playVideoModal" width="400" footer-hide @on-visible-change="onVideoModalChange">
-            <div class="modal-header" slot="header">视频播放</div>
-            <BaseVideoPlayer :videoSrc="curVideoSrc" :audioName="curVideoName" ref="videoPlayer"></BaseVideoPlayer>
-        </Modal>
-
         <!-- 底部分页区域 -->
         <Page :total="totalNum" show-sizer show-total :page-size="pageSize" :current="pageNum" @on-page-size-change="pageSizeChange" @on-change="pageChange" :page-size-opts="[5, 10, 15, 20]" />
     </div>

+ 1 - 1
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseEntryLine.vue

@@ -71,7 +71,7 @@
           },
           series: [
             {
-              name: '进线率',
+              name: that.$t('totalAnalysis.echarts_text8'),
               type: 'line',
               color: '#42beda',
               itemStyle: {

+ 2 - 2
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseKnowledgeRadar.vue

@@ -24,7 +24,7 @@
                 var option = {
                     tooltip: {
                         formatter: function(params) {
-                            var results = params.marker + '知识点占比情况<br>'
+                            var results = params.marker + that.$t('totalAnalysis.ka_title1') + '<br>'
                             for (var i = 0; i < params.value.length; i++) {
                                 results += indicator[i].name + ':' + params.value[i] + '%<br>'
                             }
@@ -104,7 +104,7 @@
                             data: [
                                 {
                                     value: data,
-                                    name: '知识点占比'
+                                    name: that.$t('totalAnalysis.ka_title1')
                                 }
                             ]
                         }

+ 1 - 1
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseLevelRadar.vue

@@ -104,7 +104,7 @@
 						},
 						data: [{
 							value: data,
-							name: '知识点占比'
+							name: that.$t('totalAnalysis.ka_text4')
 						}]
 					}]
 				}

+ 32 - 23
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseMyTable.vue

@@ -153,29 +153,38 @@
 			
 			// 筛选操作
             onFilterChange(val) {
-                let filterValue = val._filterChecked[0]
-				const ipoint = this.$store.state.totalAnalysis.analysisJson.ipoint
-				const touchScore = this.$store.state.totalAnalysis.analysisJson.touchScore
-                switch (filterValue) {
-                    case 1:
-                        this.originData = this.tableDatas.filter(item => item.score > ipoint)
-                        break
-                    case 2:
-                        this.originData = this.tableDatas.filter(item => item.score > ipoint && item.score < (ipoint + touchScore))
-                        break
-                    case 3:
-                        console.log('进步班级')
-                        break
-                    case 4:
-                        console.log('退步班级')
-                        break
-                    case 5:
-                        console.log('稳定班级')
-                        break
-                    default:
-                        this.originData = this.firstData
-                        break
-                }
+				console.log(val)
+				let filterKey = val.key
+                let filterValue = val._filterChecked.length ? val._filterChecked[0] : null
+				
+				if(filterKey === 'className'){
+					this.originData = filterValue  ? this.tableDatas.filter(item => item.className === filterValue) : this.firstData
+				}else if(filterKey === 'score'){
+					const ipoint = this.$store.state.totalAnalysis.analysisJson.ipoint
+					const touchScore = this.$store.state.totalAnalysis.analysisJson.touchScore
+					switch (filterValue) {
+					    case 1:
+					        this.originData = this.tableDatas.filter(item => item.score > ipoint)
+					        break
+					    case 2:
+					        this.originData = this.tableDatas.filter(item => item.score > ipoint && item.score < (ipoint + touchScore))
+					        break
+					    case 3:
+					        console.log('进步班级')
+					        break
+					    case 4:
+					        console.log('退步班级')
+					        break
+					    case 5:
+					        console.log('稳定班级')
+					        break
+					    default:
+					        this.originData = this.firstData
+					        break
+					}
+				}
+				
+				
                         this.pageChange(1)
             },
 

+ 5 - 3
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseScatter.vue

@@ -79,6 +79,8 @@
 					xAxis: [{
 						type: 'value',
 						splitNumber: 2,
+						min:0,
+						max:1,
 						name: _this.$t('totalAnalysis.sca_chart_text2'),
 						nameTextStyle: {
 							color: '#e4eadb'
@@ -212,7 +214,7 @@
 										position: ['5%', '10%'],
 										color: '#66ff33',
 										fontSize: 20,
-										formatter: 'A-'
+										formatter: "A'"
 									}
 
 								}, {
@@ -251,7 +253,7 @@
 										color: '#66ff33',
 										fontSize: 20,
 										zIndex: 99999,
-										formatter: 'B-'
+										formatter: "B'"
 									}
 
 								}, {
@@ -289,7 +291,7 @@
 										position: ['5%', '10%'],
 										color: '#66ff33',
 										fontSize: 20,
-										formatter: 'C-'
+										formatter: "C'"
 									}
 
 								}, {

+ 210 - 0
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseScoreRateBar.vue

@@ -0,0 +1,210 @@
+<template>
+	<div id="myScoreRateBar"></div>
+</template>
+
+<script>
+	export default {
+		name: 'hello',
+		props: ['echartsData'],
+		data() {
+			return {
+
+			}
+		},
+		created() {
+		},
+
+		methods: {
+
+			// 执行图表渲染工作
+			drawLine(data) {
+				// 基于准备好的dom,初始化echarts实例
+				let myBar = this.$echarts.init(document.getElementById('myScoreRateBar'))
+				let that = this
+
+				// 指定图表的配置项和数据
+				var option = {
+					tooltip: {
+						trigger: 'axis',
+						axisPointer: {
+							type: 'shadow',
+							textStyle: {
+								color: '#fff',
+								fontSize: '26'
+							},
+						}
+					},
+					legend: {
+						top: '5%',
+						right: '20%',
+						data: ['人数'],
+						textStyle: {
+							fontSize: 12,
+							color: '#808080'
+						},
+						icon: 'rect'
+					},
+					grid: {
+						show: false,
+						containLabel: true,
+						height: 300,
+						width: '75%',
+						top:'20%',
+						left: '6%',
+						tooltip: {
+							show: true,
+							trigger: 'axis', // 触发类型
+							textStyle: {
+								color: '#666'
+							}
+						}
+					},
+					dataZoom: [{
+						'show': true,
+						'height': 10,
+						'xAxisIndex': [
+							0
+						],
+						bottom: 40,
+						'start': 0,
+						'end': 100,
+						handleIcon: 'M512 497.821538m-418.264615 0a418.264615 418.264615 0 1 0 836.52923 0 418.264615 418.264615 0 1 0-836.52923 0Z',
+						handleSize: '160%',
+						handleStyle: {
+							color: '#d3dee5'
+					
+						},
+						textStyle: {
+							color: '#fff'
+						},
+						borderColor: '#90979c'
+					}, {
+						'type': 'inside',
+						'show': true,
+						'height': 15,
+						'start': 0,
+						'end': 100
+					}],
+					xAxis: [{
+						type: 'category',
+						axisTick: {
+							show: true
+						},
+						axisLine: {
+							show: true
+						},
+						axisLabel: {
+							color: '#aaaaaa',
+							margin: 10,
+						},
+						splitLine: {
+						    show: true,
+						    lineStyle: {
+						        color: '#4c504a',
+						        width: 0.5,
+						        type: 'solid'
+						    }
+						},
+						data: ['10%', '20%', '30%', '40%','50%', '60%', '70%', '80%','90%', '100%'],
+
+					}],
+					yAxis: [{
+						name: '人数',
+						nameTextStyle: {
+							color: '#808080',
+							fontSize: 12,
+						},
+						type: 'value',
+						axisLine: {
+							show: false
+						},
+						axisLabel: {
+							color: '#afafaf',
+							fontSize: 12,
+						},
+						splitLine: {
+						    show: true,
+						    lineStyle: {
+						        color: '#4c504a',
+						        width: 0.5,
+						        type: 'solid'
+						    }
+						},
+						axisTick: {
+							show: true
+						}
+					}],
+					series: [{
+							name: '人数',
+							type: 'bar',
+							label: {
+								show: true,
+								position: 'top',
+								fontSize: 14,
+								color: '#3DC3F0',
+								fontWeight: 'bold'
+							},
+							barMaxWidth: 40,
+							itemStyle: {
+								color: {
+									type: 'linear',
+									x: 0,
+									y: 0,
+									x2: 0,
+									y2: 1,
+									colorStops: [{
+										offset: 0,
+										color: '#3DC3F0' // 0% 处的颜色
+									}, {
+										offset: 1,
+										color: '#3486b1' // 100% 处的颜色
+									}]
+								}
+							},
+							data: [15,8,6,20,0,14,18,22,34,5]
+						},
+					]
+				};
+				// 绘制图表
+				myBar.setOption(option)
+				window.addEventListener('resize', function() {
+				    myBar.resize()
+				})
+			},
+
+
+			doRender(val) {
+			}
+		},
+		mounted() {
+			this.drawLine()
+			if (this.getBaseBarData) {
+				console.log('BaseBar接收到的vuex', this.getBaseBarData)
+				this.doRender(this.getBaseBarData)
+				this.drawLine()
+			}
+		},
+		computed: {
+			// 获取最新柱状图数据
+			getBaseBarData() {
+				return this.$store.state.totalAnalysis.analysisJson
+			}
+		},
+		watch: {
+			getBaseBarData(val) {
+				if (!val) return
+				this.drawLine()
+				console.log('BaseBar接收到watch的vuex', val)
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	#myScoreRateBar {
+		width: 100%;
+		height: 500px;
+		margin: 0 auto;
+		display: block;
+	}
+</style>

+ 5 - 3
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseTestScatter.vue

@@ -73,11 +73,13 @@
 					xAxis: [{
 						type: 'value',
 						splitNumber: 2,
+						min:0,
+						max:1,
 						name: _this.$t('totalAnalysis.ta_chart_text3'),
 						nameTextStyle: {
 							color: '#e4eadb'
 						},
-						scale: true,
+						scale: false,
 						splitLine: {
 							show: true,
 							lineStyle: {
@@ -187,7 +189,7 @@
 										position: ['5%', '10%'],
 										color: '#66ff33',
 										fontSize: 20,
-										formatter: 'B-'
+										formatter: "B'"
 									}
 
 								}, {
@@ -225,7 +227,7 @@
 										position: ['5%', '40%'],
 										color: '#66ff33',
 										fontSize: 20,
-										formatter: 'A-'
+										formatter: "A'"
 									}
 								}, {
 									xAxis: '0.5',

+ 1 - 1
TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue

@@ -3,7 +3,7 @@
 		<Form ref="voteForm" :model="voteForm" label-position="top" :rules="ruleValidate" :disabled="!voteFormEdit"
 		 hide-required-mark>
 			<FormItem :label="$t('vote.form.name')" prop="name">
-				<Input :class="!voteFormEdit ? 'vote-form-disabled':''" v-model="voteForm.name" placeholder="请输入投票名称"></Input>
+				<Input :class="!voteFormEdit ? 'vote-form-disabled':''" v-model="voteForm.name" :placeholder="$t('vote.form.namePlace')"></Input>
 			</FormItem>
 			<FormItem :label="$t('vote.form.target')" prop="classes">
 				<RadioGroup v-model="classType" @on-change="onClassTypeChange" v-if="voteFormEdit">

+ 1 - 1
TEAMModelOS/ClientApp/src/components/vote/BaseVoteTable.vue

@@ -33,7 +33,7 @@
                         title: vm.$t('vote.option'),
                         key: 'option',
                         render: (h, params) => {
-                            return h('span', params.row.option === 'Null' ? '未投票' : params.row.option)
+                            return h('span', params.row.option === 'Null' ? vm.$t('vote.noVote') : params.row.option)
                         },
                     },
                     {

+ 13 - 1
TEAMModelOS/ClientApp/src/locale/lang/en-US/system.js

@@ -33,6 +33,18 @@ export default {
         prtQu:'个人问卷',
         selfLearn:'自主学习',
         homework:'作业活动',
-        acRecord:'活动记录'
+        acRecord: '活动记录',
+        cusMgt:'课程管理'
+    },
+    compt: {
+        cusWare: '课件',
+        sizeErr: '文件大小超出限制',
+        typeErr: '文件类型不支持',
+        acRep: '警告 :未找到指定班级',
+        classErr: '警告 :未找到指定班级',
+        setErr: '错误:座位号重复',
+        tbColErr1:'导入数据没有',
+        tbColErr2: ',请完善表格数据再导入',
+        fileReadErr:'文件读取失败'
     }
 }

+ 6 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/evaluation.js

@@ -259,5 +259,10 @@ export default {
 		formatErrorTip:'请输入正确格式的网址地址!',
 		noCompleteTip:'请填写完整',
 	},
-	completeCount:'填空数量'
+	completeCount:'填空数量',
+	addTip1:'当前配分超过试卷总分,请重新分配!',
+	addTip2:'最多只有10个选项!',
+	addTip3:'至少保留一个正确答案!',
+	addTip4:'至少保留两个选项!',
+	addTip5:'没有查询到题目!'
 }

+ 13 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/system.js

@@ -33,6 +33,18 @@ export default {
         prtQu:'个人问卷',
         selfLearn:'自主学习',
         homework:'作业活动',
-        acRecord:'活动记录'
+        acRecord: '活动记录',
+        cusMgt:'课程管理'
+    },
+    compt: {
+        cusWare: '课件',
+        sizeErr: '文件大小超出限制',
+        typeErr: '文件类型不支持',
+        acRep: '警告 :未找到指定班级',
+        classErr: '警告 :未找到指定班级',
+        setErr: '错误:座位号重复',
+        tbColErr1:'导入数据没有',
+        tbColErr2: ',请完善表格数据再导入',
+        fileReadErr:'文件读取失败'
     }
 }

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

@@ -4,6 +4,11 @@ export default {
 		tab1:'统计数据',
 		tab2:'评测数据',
 	},
+	noData:'暂无有效数据返回!',
+	allClasses:'所有班级',
+	all:'全部',
+	classBaseInfo:'班级基本数据',
+	scoreRate:'得分率分布图',
     // EvaluationList.vue
     text1: '历次考试汇总',
     text2: '次数',
@@ -81,10 +86,10 @@ export default {
 
     // AchievementAnalysis.vue
     ach_title1: '得分率统计',
-    ach_title2: '均分分析',
+    ach_title2: '平均分数统计',
     ach_title3: '进线人数统计',
     ach_title4: '进线情况统计',
-    ach_title5: '进线率统计',
+    ach_title5: '各班平均与进线率统计',
     ach_title6: '预警统计',
     ach_title7: '排名统计',
     ach_title8: '均分分析',
@@ -94,8 +99,8 @@ export default {
     ach_text4: '班级平均分',
     ach_text5: '校级平均分',
     ach_text6: '区级平均分',
-    ach_text7: '人数',
-    ach_text8: '进线人数',
+    ach_text7: '人数',
+    ach_text8: '进线人数',
     ach_text9: '进线率',
     ach_text10: '当前班级',
     ach_text11: '总人数',
@@ -108,8 +113,8 @@ export default {
     ach_table_text5: '超均率',
     ach_table_text6: '进线',
     ach_table_text7: '踩线',
-    ach_table_text8: '班级排名',
-    ach_table_text9: '年级排名',
+    ach_table_text8: '班级排名(PR排名)',
+    ach_table_text9: '年级排名(PR排名)',
     ach_table_text10: '区级排名',
     ach_table_text11: '班级PR排名',
     ach_table_text12: '年级PR排名',

+ 34 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/utils.js

@@ -3,5 +3,38 @@ export default {
 	videoFormatError:'视频格式不正确!请重新选择!',
 	audioFormatError:'音频格式不正确!请重新选择!',
 	fileReadFail:'有试题数据读取失败!',
-	uploadLoading:'上传中...'
+	uploadLoading:'上传中...',
+	draw:'绘制',
+	text:'文本输入',
+	clear:'清屏',
+	undo:'撤销',
+	close:'关闭',
+	save:'保存',
+	width:'画笔粗细',
+	color:'画笔颜色',
+	fontSize:'字体大小',
+	fontColor:'字体颜色',
+	newNotice:'新通知',
+	noData:'暂无数据',
+	noJoinSchool:'暂未加入学校',
+	noShoolTip:'用户暂无学校列表数据',
+	getDataFail:'获取数据失败',
+	teacher:'教师',
+	student:'学生',
+	accountManage:'账号管理',
+	courseNum:'任教课程数',
+	activityNum:'发布活动数',
+	classNum:'任教班级数',
+	full:'已满',
+	spaceStatus:'个人空间状态',
+	res:'教材',
+	img:'图片',
+	video:'视频',
+	audio:'音频',
+	doc:'文档',
+	bank:'题库',
+	other:'其他内容',
+	caclErrorL:'空间计算异常',
+	logout:'退出登录',
+	
 }

+ 6 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/evaluation.js

@@ -259,5 +259,10 @@ export default {
 	formatErrorTip:'請輸入正確格式的網址地址!',
 	noCompleteTip:'請填寫完整',
 	},
-	completeCount:'填空數量'
+	completeCount:'填空數量',
+	addTip1:'當前配分超過試卷總分,請重新分配!',
+	addTip2:'最多只有10個選項!',
+	addTip3:'至少保留一個正確答案!',
+	addTip4:'至少保留兩個選項!',
+	addTip5:'沒有査詢到題目!'
 }

+ 13 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/system.js

@@ -33,6 +33,18 @@ export default {
         prtQu: '個人問卷',
         selfLearn: '自主學習',
         homework: '工作活動',
-        acRecord: '活動記錄'
+        acRecord: '活動記錄',
+        cusMgt: '課程管理'
+    },
+    compt: {
+        cusWare: '課件',
+        sizeErr: '文件大小超出限制',
+        typeErr: '檔案類型不支持',
+        acRep: '警告:未找到指定班級',
+        classErr: '警告:未找到指定班級',
+        setErr: '錯誤:座位號重複',
+        tbColErr1: '導入數據沒有',
+        tbColErr2: ',請完善表格數據再導入',
+        fileReadErr: '檔案讀取失敗'
     }
 }

+ 12 - 7
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/totalAnalysis.js

@@ -3,7 +3,12 @@ export default {
 		title: '學情分析儀錶盤',
 		tab1: '統計資料',
 		tab2: '評測數據',
+		noData:'暫無有效數據返回!'
 	},
+	allClasses:'所有班級',
+	all:'全部',
+	classBaseInfo:'班級基本數據',
+	scoreRate:'得分率分佈圖',
 	// EvaluationList.vue
 	text1: '歷次考試匯總',
 	text2: '次數',
@@ -81,10 +86,10 @@ export default {
 
 	// AchievementAnalysis.vue
 	ach_title1: '得分率統計',
-	ach_title2: '均分分析',
+	ach_title2: '平均分數統計',
 	ach_title3: '進線人數統計',
 	ach_title4: '進線情况統計',
-	ach_title5: '進線率統計',
+	ach_title5: '各班平均與進線率統計',
 	ach_title6: '預警統計',
 	ach_title7: '排名統計',
 	ach_title8: '均分分析',
@@ -94,9 +99,9 @@ export default {
 	ach_text4: '班級平均分',
 	ach_text5: '校級平均分',
 	ach_text6: '區級平均分',
-	ach_text7: '人數',
-	ach_text8: '進線總人數',
-	ach_text9: '進線率',
+	ach_text7: '人數',
+	ach_text8: '達標人數',
+	ach_text9: '達標率',
 	ach_text10: '當前班級',
 	ach_text11: '總人數',
 	ach_text12: '返回',
@@ -108,8 +113,8 @@ export default {
 	ach_table_text5: '超均率',
 	ach_table_text6: '進線',
 	ach_table_text7: '踩線',
-	ach_table_text8: '班級排名',
-	ach_table_text9: '年級排名',
+	ach_table_text8: '班級排名(PR排名)',
+	ach_table_text9: '年級排名(PR排名)',
 	ach_table_text10: '區級排名',
 	ach_table_text11: '班級PR排名',
 	ach_table_text12: '年級PR排名',

+ 33 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/utils.js

@@ -3,5 +3,37 @@ export default {
 	videoFormatError: '視頻格式不正確!請重新選擇!',
 	audioFormatError: '音訊格式不正確!請重新選擇!',
 	fileReadFail: '有試題數據讀取失敗!',
-	uploadLoading: '上傳中…'
+	uploadLoading: '上傳中…',
+	draw: '繪製',
+	text: '文字輸入',
+	clear: '清屏',
+	undo: '撤銷',
+	close: '關閉',
+	save: '保存',
+	width: '畫筆粗細',
+	color: '畫筆顏色',
+	fontSize: '字體大小',
+	fontColor: '字體顏色',
+	newNotice: '新通知',
+	noData: '暫無數據',
+	noJoinSchool: '暫未加入學校',
+	noShoolTip: '用戶暫無學校清單數據',
+	getDataFail: '獲取數據失敗',
+	teacher: '教師',
+	student: '學生',
+	accountManage: '帳號管理',
+	courseNum: '任教課程數',
+	activityNum: '發佈活動數',
+	classNum: '任教班級數',
+	full: '已滿',
+	spaceStatus: '個人空間狀態',
+	res: '教材',
+	img: '圖片',
+	video: '視頻',
+	audio: '音訊',
+	doc: '檔案',
+	bank: '題庫',
+	other: '其他內容',
+	caclErrorL: '空間計算异常',
+	logout: '登出',
 }

+ 1 - 0
TEAMModelOS/ClientApp/src/service/User.js

@@ -76,6 +76,7 @@ export class User {
           localStorage.removeItem('user_profile')
           localStorage.removeItem('school_profile')
           localStorage.removeItem('student_profile')
+          localStorage.removeItem('filterConditions')
           
           // 重置登录状态
           User.$access.reset();

+ 1 - 0
TEAMModelOS/ClientApp/src/utils/editorTools.js

@@ -345,6 +345,7 @@ export default {
 							}),
 							h('BaseMyCanvas', {
 								props:{
+									vm:vm
 								},
 								on: {
 									onSaveCanvas(val) {

+ 2 - 2
TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue

@@ -325,7 +325,7 @@
 			 * @param code
 			 */
 			getPeriodName(code) {
-				return this.$store.state.user.schoolProfile.school_base ? this.$store.state.user.schoolProfile.school_base.period.filter(i => i.id === code)[0].name : '暂无'
+				return this.$store.state.user.schoolProfile.school_base ? this.$store.state.user.schoolProfile.school_base.period.filter(i => i.id === code)[0].name : this.$t('evaluation.noData')
 			},
 
 			/**
@@ -334,7 +334,7 @@
 			 */
 			getGradeName(periodId, code) {
 				return this.$store.state.user.schoolProfile.school_base ? this.$store.state.user.schoolProfile.school_base.period.filter(i => i.id === periodId)[0].grades.filter(j =>
-					j.id === code)[0].name : '空'
+					j.id === code)[0].name : this.$t('evaluation.noData')
 			},
 
 			/**

+ 1 - 1
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseCreateChild.vue

@@ -73,7 +73,7 @@
 		</div>
 
 		<!-- 选择知识点弹窗 -->
-		<Modal v-model="selectPointsModal" :title="'选择知识点'" width="600px" class="related-point-modal" style="z-index: 99999">
+		<Modal v-model="selectPointsModal" :title="$t('evaluation.newExercise.choosePoint')" width="600px" class="related-point-modal" style="z-index: 99999">
 			<BasePoints v-if="selectPointsModal" ref="pointRef" :period="schoolInfo.period[curPeriodIndex].id" :subject="schoolInfo.period[curPeriodIndex].subjects[curSubjectIndex].id"
 			 @onCheckChange="onCheckChange" :points="exercisePoints" :scope="curScope"></BasePoints>
 			<!--<CreateNewChild v-if="isLoadModal" ref="newChild" :isChildEdit="isChildEdit" :editItem="editChild"></CreateNewChild>-->

+ 2 - 5
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseEditExercise.vue

@@ -52,7 +52,7 @@
 						<span class="exercise-item-point-close"> 
 							<Icon type="md-close" @click="onDeletePoint(index)" /></span>
 					</span>
-					<span class="exercise-item-point-modify" @click="selectPointsModal = true">修改</span>
+					<span class="exercise-item-point-modify" @click="selectPointsModal = true">{{ this.$t('evaluation.newExercise.modify') }}</span>
 				</div>
 			</div>
 		</div>
@@ -418,10 +418,7 @@
 						// 如果是试卷内编辑试题 则返回编辑好的数据 再统一进行保存
 						this.saveExercise(exerciseItem);
 					}
-				} else if (exerciseItem.level === 0) {
-					this.$Message.warning("题目难度未设置!");
-					this.isLoading = false;
-				} else {
+				} else{
 					this.$Message.warning(this.$t('evaluation.newExercise.unCompleteTip'));
 					this.isLoading = false;
 				}

+ 2 - 2
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseExerciseList.vue

@@ -519,7 +519,7 @@
 				/** 重新计算剩余分配分数 */
 				this.surPlusScore = this.paperInfo.score - this.groupTypeList.reduce((p, e) => parseInt(p) + parseInt(e.score), 0)
 				if (this.surPlusScore < 0) {
-					this.$Message.warning("当前配分超过试卷总分,请重新分配!")
+					this.$Message.warning(this.$t('totalAnalysis.addTip1'))
 				} else {
 					/* 按照题型配分后平均分配给每个子题 */
 					this.groupTypeList.forEach(item => {
@@ -567,7 +567,7 @@
 				
 				this.$refs.paperEdit.isLoading = false
 				this.editExerciseModal = false
-				this.$Message.success("修改成功!")
+				this.$Message.success(this.$t('evaluation.editSuc'))
 				
 				this.exerciseList.splice(this.currentExerciseIndex, 1, item)
 				this.curTypeItems.splice(this.curIndex, 1, item)

+ 1 - 1
TEAMModelOS/ClientApp/src/view/evaluation/components/BasePointPie.vue

@@ -80,7 +80,7 @@
 			})
 			let typeList = this._.groupBy(tempArr, 'knowledge')
 			for (let key in typeList) {
-				let newKey = key === 'undefined' || !key ?  '未绑定知识点' : key
+				let newKey = key === 'undefined' || !key ?  this.$t('evaluation.noPoints') : key
 				let isExistIndex = arr.map(i => i.name).indexOf(newKey)
 				if(arr.length && isExistIndex > -1){
 					arr[isExistIndex].value = arr[isExistIndex].value + typeList[key].length

+ 1 - 2
TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue

@@ -901,8 +901,7 @@
 							}
 						})
 					} catch (e) {
-						this.$Message.error('上传失败!')
-						console.log(e)
+						this.$Message.error(this.$t('evaluation.paperList.saveItemsFailTip'))
 						this.isLoading = false
 					}
 				})

+ 4 - 4
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseMultiple.vue

@@ -132,7 +132,7 @@
 						this.refreshOrder()
 					})
 				} else {
-					this.$Message.warning('最多只有10个选项!')
+					this.$Message.warning(this.$t('evaluation.addTip2'))
 				}
 			},
 			
@@ -142,7 +142,7 @@
 				this.$nextTick(() => {
 				    if (this.trueArr.indexOf(index) > -1) {
 						if(this.trueArr.length === 1){
-							this.$Message.warning('至少保留一个正确答案!')
+							this.$Message.warning(this.$t('evaluation.addTip3'))
 						}else{
 							this.trueArr.splice(this.trueArr.indexOf(index), 1)
 						}
@@ -197,7 +197,7 @@
 					// 如果删除的是正确答案 则重置正确答案
 					if(this.trueArr.indexOf(index) > -1){
 						if(this.trueArr.length === 1){
-							this.$Message.warning('至少保留一个正确答案!')
+							this.$Message.warning(this.$t('evaluation.addTip3'))
 						}else{
 							this.trueArr.splice(this.trueArr.indexOf(index),1)
 							// 确保当前存在的options保持同步
@@ -223,7 +223,7 @@
 					}
 					
 				} else {
-					this.$Message.warning('至少保留两个选项!')
+					this.$Message.warning(this.$t('evaluation.addTip4'))
 				}
 			},
 

+ 2 - 2
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue

@@ -127,7 +127,7 @@
 						this.refreshOrder()
 					})
 				} else {
-					this.$Message.warning('最多只有10个选项!')
+					this.$Message.warning(this.$t('evaluation.addTip2'))
 				}
 			},
 
@@ -187,7 +187,7 @@
 					// 刷新选项序号显示
 					this.refreshOrder()
 				} else {
-					this.$Message.warning('至少保留两个选项!')
+					this.$Message.warning(this.$t('evaluation.addTip4'))
 				}
 			},
 

+ 1 - 1
TEAMModelOS/ClientApp/src/view/learnactivity/ManualCreate.vue

@@ -117,7 +117,7 @@
                 <!-- <Loading :top="100" v-show="isLoading"></Loading> -->
                 <ExerciseList ref="exList" :selQue="selQue" :propsList="questionList" @pageScroll="doScroll"
 				 @on-question-change="selectQuestion"></ExerciseList>
-                <EmptyData style="margin-top:120px;" v-if="!isLoading && questionList.length == 0" textContent="没有查询到题目"></EmptyData>
+                <EmptyData style="margin-top:120px;" v-if="!isLoading && questionList.length == 0" :textContent="$t('evaluation.addTip5')"></EmptyData>
                 <!-- <div class="page-wrap">
                     <Page :current.sync="pageNum" :total="totalNum" show-total :page-size="pageSize" size="small" show-sizer @on-change="getCurrentPageData" />
                 </div> -->

+ 1 - 1
TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue

@@ -506,7 +506,7 @@
 						let itemJson = JSON.parse(await this.$tools.getFile(blobHost + url + sasString.sas))
 						resolve(itemJson)
 					}catch(e){
-						this.$Message.error('文件获取失败!')
+						this.$Message.error(this.$t('vote.getDataFailTip'))
 						reject(e)
 					}
 				})

+ 10 - 5
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/AchievementAnalysis.vue

@@ -8,9 +8,11 @@
             <div class="percent-item" v-for="(item,index) in passRate" :key="index">
                 <div class="fl-col-center">
                     <span class="percent-name">{{item.name}}</span>
-                    <span class="percent-value"><span class="percent-line" :style="{background:colorList[index]}"></span>{{item.class}}</span>
-                    <!-- <span class="percent-grade-value">{{$t('totalAnalysis.ach_text2')}}:{{item.grade}}</span> -->
-                    <!-- <span class="percent-area-value">{{$t('totalAnalysis.ach_text3')}}:{{item.area}}</span> -->
+                    <span class="percent-value"><span class="percent-line" :style="{background:colorList[index]}"></span>{{item.value}}</span>
+					<div style="margin-left: 30px;">
+						<p>平均分:110</p>
+						<p>标准差:20</p>
+					</div>
                 </div>
             </div>
         </Row>
@@ -137,7 +139,10 @@
 			/* 获取成绩分析模块 -- 及格率统计数据 */
 			getPassRate(analysisJson){
 				console.log(analysisJson)
-				let result = []
+				let result = [{
+					name:'全科',
+					value: '88.8%'
+				}]
 				analysisJson.subjects.forEach((item,index) => {
 					let o = {}
 					o.name = item.name
@@ -147,7 +152,7 @@
 					})
 					result.push({
 						name:item.name,
-						class:(+(classAverage / analysisJson.classes.length) * 100).toFixed(1) + '%',
+						value:(+(classAverage / analysisJson.classes.length) * 100).toFixed(1) + '%',
 					})
 				})
 				return result

File diff suppressed because it is too large
+ 532 - 506
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/EarlyWarning.vue


+ 36 - 12
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/EntryTables.vue

@@ -49,7 +49,11 @@
                     },
                     {
                         title: this.$t('totalAnalysis.base_class'),
-                        key: 'className'
+                        key: 'className',
+						filters: [],
+						filterMultiple: false,
+						filterRemote(value, row) {
+						}
                     },
                     {
                         title: this.$t('totalAnalysis.ach_table_text1'),
@@ -84,18 +88,28 @@
                     },
                     {
                         title: this.$t('totalAnalysis.base_class'),
-                        key: 'name'
+                        key: 'className',
+						filters: [],
+						filterMultiple: false,
+						filterRemote(value, row) {
+				 		}
                     },
+					{
+					    title: this.$t('totalAnalysis.sca_chart_text1'),
+					    key: 'scoreRate',
+					    sortable: 'custom',
+					    minWidth: 50
+					},
+					{
+					    title: this.$t('totalAnalysis.ach_text7'),
+					    key: 'totalNum',
+					    sortable: true
+					},
                     {
                         title: this.$t('totalAnalysis.ach_text8'),
                         key: 'entryNum',
                         sortable: true
                     },
-                    {
-                        title: this.$t('totalAnalysis.ach_text7'),
-                        key: 'totalNum',
-                        sortable: true
-                    },
                     {
                         title: this.$t('totalAnalysis.ach_text9'),
                         key: 'overAverageRate',
@@ -108,7 +122,7 @@
 					    title: this.$t('totalAnalysis.ach_table_text3'),
 					    key:'average',
 					    renderType: function(h, params) {
-					        return h('span', (Number(params.row.average)).toFixed(2))
+					        return h('span', (Number(params.row.average)).toFixed(1))
 					    },
 					    sortable: 'custom'
 					},
@@ -177,18 +191,18 @@
 				analysisJson.classes.forEach((classItem,classIndex) => {
 					result.push({
 						gradeRank:0,
-						name:classItem.className,
+						className:classItem.className,
 						entryNum:classItem.lineCount,
 						totalNum:classItem.stuCount,
 						overAverageRate:classItem.stuCount > 0 ? ((classItem.lineCount / classItem.stuCount) * 100).toFixed(2) : 0.00,
-						average:classItem.totalAverage,
-						standardDeviation:classItem.standardDeviation.toFixed(2),
+						average:classItem.totalAverage.toFixed(1),
+						standardDeviation:classItem.standardDeviation.toFixed(1),
 					})
 				})
 				/* 根据超均率 来对班级进行年级排名 */
 				let rateRanks = result.sort((a, b) => { return Number(b.average) - Number(a.average) })
 				result.forEach(item => {
-					item.gradeRank = rateRanks.map(i => i.name).indexOf(item.name) + 1
+					item.gradeRank = rateRanks.map(i => i.className).indexOf(item.className) + 1
 				})
 				return result
 			}
@@ -201,6 +215,16 @@
 				this.renderColumns(this.getAnalysisJson) // 渲染科目表头
 				this.entryTableData = this.getTableDatas(this.getAnalysisJson)
 				this.entryBarData = this.getEntryBarData(this.getAnalysisJson)
+				
+				let filterArr = []
+				this.getAnalysisJson.classes.forEach(i => {
+					filterArr.push({
+						label:i.className,
+						value:i.className
+					})
+				})
+				this.entryRateColumns[1].filters = filterArr
+				this.entryNumberColumns[1].filters = filterArr
             }
         },
         computed: {

+ 2 - 1
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.less

@@ -348,9 +348,10 @@
         .filter-item {
             background: #0087af;
             color: #fff;
-            padding: 2px 5px;
+            padding: 4px 7px;
             margin-left: 15px;
 			font-size: 12px;
+			border-radius: 4px;
         }
 
         .filter-item .ivu-icon {

+ 97 - 83
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.vue

@@ -77,14 +77,14 @@
 							<div class="el-filter-item">
 								<span class="el-filter-title">{{ $t("totalAnalysis.condition2") }}:</span>
 								<RadioGroup v-model="filterGrade" type="button" @on-change="filterGradeChange">
-									<Radio label="全部">全部</Radio>
+									<Radio :label="$t('totalAnalysis.all')">{{ $t('totalAnalysis.all') }}</Radio>
 									<Radio v-for="(item, index) in filterGradeList" :label="item.name" :key="index">{{ item.name }}</Radio>
 								</RadioGroup>
 							</div>
 							<div class="el-filter-item">
 								<span class="el-filter-title">{{ $t("totalAnalysis.condition7") }}:</span>
 								<RadioGroup v-model="filterSubject" type="button" @on-change="filterSubjectChange">
-									<Radio label="全部">全部</Radio>
+									<Radio :label="$t('totalAnalysis.all')">{{ $t('totalAnalysis.all') }}</Radio>
 									<Radio v-for="(item, index) in filterSubjectList" :label="item.name" :key="index">{{ item.name }}</Radio>
 								</RadioGroup>
 							</div>
@@ -100,22 +100,6 @@
 									<Radio v-for="(item, index) in filterData.termList" :label="item.name" :key="index">{{ item.name }}</Radio>
 								</RadioGroup>
 							</div>
-
-							<!-- 考试范围暂未实际有效字段 -->
-							<!-- <div class="el-filter-item">
-                                        <span class="el-filter-title">{{ $t("totalAnalysis.condition5") }}:</span>
-                                        <RadioGroup v-model="filterArea" type="button" @on-change="filterAreaChange">
-                                            <Radio v-for="(item, index) in filterData.areaList" :label="item.name" :key="index">{{ item.name }}</Radio>
-                                        </RadioGroup>
-                                    </div> -->
-							<!-- 评测来源暂未实际有效字段 -->
-							<!-- <div class="el-filter-item">
-                                        <span class="el-filter-title">{{ $t("totalAnalysis.condition6") }}:</span>
-                                        <RadioGroup v-model="filterFeedback" type="button" @on-change="filterFeedbackChange">
-                                            <Radio v-for="(item, index) in filterData.feedbackList" :label="item.name" :key="index">{{ item.name }}</Radio>
-                                        </RadioGroup>
-                                    </div> -->
-
 						</div>
 					</transition>
 					<div class="el-bread">
@@ -160,11 +144,15 @@
 									<!-- 暂无参与率数据 -->
 									{{ getJoinRate(item) }}
 								</span>
+								<span>{{ $t("totalAnalysis.sca_chart_text1") }}:
+									<!-- 得分率数据 -->
+									<!-- {{ item.score.toFixed(2) + '%' }} -->
+								</span>
 								<!-- <span>{{ $t("totalAnalysis.echarts_text15") }}:
 										</span> -->
 							</div>
 						</div>
-						<Page size="small" />
+						<!-- <Page size="small" /> -->
 					</div>
 				</div>
 			</div>
@@ -187,7 +175,7 @@
 			BaseSubjectBar,
 			BaseClassBar,
 		},
-		data() {
+		data(vm) {
 			return {
 				currentPanel: "",
 				isLoadingList: false,
@@ -199,7 +187,6 @@
 				classList: new Array(11).fill("1"),
 				gradeList: [],
 				geniusLineData: null,
-				semesterList: ["2019上学期", "2019下学期"],
 				activeGradeIndex: null,
 				arrowLeft: 0,
 				selectSemester: 0,
@@ -217,29 +204,48 @@
 				filterData: {},
 				searchValue: "",
 				searchList: [],
-				filterPeriod: "全部",
-				filterGrade: "全部",
-				filterTerm: "全部",
-				filterType: "全部",
-				filterArea: "全部",
-				filterFeedback: "全部",
-				filterSubject: "全部",
+				filterPeriod: vm.$t('totalAnalysis.all'),
+				filterGrade: vm.$t('totalAnalysis.all'),
+				filterTerm: vm.$t('totalAnalysis.all'),
+				filterType: vm.$t('totalAnalysis.all'),
+				filterArea: vm.$t('totalAnalysis.all'),
+				filterFeedback: vm.$t('totalAnalysis.all'),
+				filterSubject: vm.$t('totalAnalysis.all'),
 				schoolData: {
 					name: "",
 					period: []
 				},
 				defaultAll: {
-					name: '全部',
+					name: vm.$t('totalAnalysis.all'),
 					id: '0'
 				},
 				evType: {
-					regular: '正规考',
-					simulation: '模拟考',
-					normal: '普通考'
-				}
+					regular: vm.$t('totalAnalysis.ti_text6'),
+					simulation: vm.$t('totalAnalysis.ti_text7'),
+					normal: vm.$t('totalAnalysis.ti_text8')
+				},
+				typeList: [
+				  {
+				    "name": vm.$t('totalAnalysis.all'),
+				    "key": "all"
+				  },
+				  {
+				    "key": "regular",
+				    "name": vm.$t('totalAnalysis.ti_text6')
+				  },
+				  {
+				    "key": "simulation",
+				    "name": vm.$t('totalAnalysis.ti_text7')
+				  },
+				  {
+				    "key": "normal",
+				    "name": vm.$t('totalAnalysis.ti_text8')
+				  }
+				],
 			};
 		},
 		created() {
+			
 			this.getSchoolInfo();
 			// this.getHomePageData();
 			this.getExamList();
@@ -252,18 +258,7 @@
 					let schoolBaseInfo = res.school_base;
 					if (schoolBaseInfo) {
 						this.schoolData = schoolBaseInfo;
-						//默认选中第一个学段
-						if (this.schoolData.period && this.schoolData.period.length) {
-							this.filterPeriod = this.schoolData.period[0].name
-							this.filterPeriodChange()
-						}
-						//年级和学科默认选中全部
-						// if (this.filterConditions.period && this.schoolData.period[0].grades.length) {
-						//     this.filterGrade = this.schoolData.period[0].grades[0].name
-						//     this.filterGradeChange()
-						// }
-						console.log(this.filterConditions)
-						let filterJson = this.$store.state.totalAnalysis.filterData
+						
 						if (schoolBaseInfo.period.length) {
 							this.filterData.periodList = [this.defaultAll].concat(schoolBaseInfo.period);
 							this.filterData.gradeList = [this.defaultAll].concat(schoolBaseInfo.period[0].grades);
@@ -271,9 +266,22 @@
 								.subjects);
 							this.filterData.termList = [this.defaultAll].concat(schoolBaseInfo.period[0]
 							.semesters);
-							this.filterData.typeList = filterJson.typeList;
-							this.filterData.areaList = filterJson.areaList;
-							this.filterData.feedbackList = filterJson.feedbackList;
+							this.filterData.typeList = this.typeList;
+						}
+						
+						if(localStorage.getItem('filterConditions')){
+							this.filterConditions = JSON.parse(localStorage.getItem('filterConditions'))
+							this.filterPeriod = this.filterConditions.period || this.$t('totalAnalysis.all')
+							this.filterGrade = this.filterConditions.grade || this.$t('totalAnalysis.all')
+							this.filterSubject = this.filterConditions.subject || this.$t('totalAnalysis.all')
+							this.filterType = this.evType[this.filterConditions.type] || this.$t('totalAnalysis.all')
+							this.filterTerm = this.filterConditions.term || this.$t('totalAnalysis.all')
+						}
+						console.log(this.filterConditions)
+						//默认选中第一个学段
+						if (this.schoolData.period && this.schoolData.period.length && !localStorage.getItem('filterConditions')) {
+								this.filterPeriod = this.schoolData.period[0].name
+								this.filterPeriodChange()
 						}
 					}
 				});
@@ -292,7 +300,7 @@
 							this.gradeList = res.result.data;
 							this.geniusLineData = res.result.data[0];
 						} else {
-							this.$Message.warning("暂无有效数据返回");
+							this.$Message.warning(this.$t('totalAnalysis.noData'));
 						}
 						this.isLoadingList = false;
 						// this.$refs.geniusLine.dataLoading = false
@@ -300,7 +308,7 @@
 					.catch((err) => {
 						console.log(err);
 						this.isLoadingList = false;
-						this.$Message.error("服务器繁忙,请稍后重试!");
+						this.$Message.error(this.$t('http.error500'));
 					});
 			},
 
@@ -321,9 +329,7 @@
 							this.searchList = this.examList.length ? this.examList.map((item) => item.name) : []
 							this.$store.commit("updateExamList", res.examInfo);
 							this.isLoadingList = false;
-							// setTimeout(() => {
-							//     this.doFilter()
-							// }, 2000);
+							
 							this.doFilter()
 						} else {
 							this$Message.error('API ERROR!')
@@ -364,27 +370,27 @@
 						// this.filterConditions.period = null;
 						break;
 					case "grade":
-						this.filterGrade = "全部";
+						this.filterGrade = this.$t('totalAnalysis.all');
 						this.filterConditions.grade = null;
 						break;
 					case "term":
-						this.filterTerm = "全部";
+						this.filterTerm = this.$t('totalAnalysis.all');
 						this.filterConditions.term = null;
 						break;
 					case "type":
-						this.filterType = "全部";
+						this.filterType = this.$t('totalAnalysis.all');
 						this.filterConditions.type = null;
 						break;
 					case "area":
-						this.filterArea = "全部";
+						this.filterArea = this.$t('totalAnalysis.all');
 						this.filterConditions.area = null;
 						break;
 					case "feedback":
-						this.filterFeedback = "全部";
+						this.filterFeedback = this.$t('totalAnalysis.all');
 						this.filterConditions.feedback = null;
 						break;
 					case "subject":
-						this.filterSubject = "全部";
+						this.filterSubject = this.$t('totalAnalysis.all');
 						this.filterConditions.subject = null;
 						break;
 					default:
@@ -396,27 +402,27 @@
 			},
 
 			filterPeriodChange() {
-				this.filterConditions.period = this.filterPeriod === "全部" ? null : this.filterPeriod;
+				this.filterConditions.period = this.filterPeriod === this.$t('totalAnalysis.all') ? null : this.filterPeriod;
 				// 切换学科后年级会变化,需要初始化年级状态 默认选中全部
 				if (this.filterGradeList && this.filterGradeList.length) {
-				    this.filterGrade = "全部"
+				    this.filterGrade = this.$t('totalAnalysis.all')
 				    this.filterGradeChange()
 				}
 				// 切换学科后学科会变化,需要初始化学科状态 默认选中全部
 				if (this.filterSubjectList && this.filterSubjectList.length) {
-				    this.filterSubject = "全部"
+				    this.filterSubject = this.$t('totalAnalysis.all')
 				    this.filterSubjectChange()
 				}
 				this.doFilter();
 			},
 			filterGradeChange() {
 				this.filterConditions.grade =
-					this.filterGrade === "全部" ? null : this.filterGrade;
+					this.filterGrade === this.$t('totalAnalysis.all') ? null : this.filterGrade;
 				this.doFilter();
 			},
 			filterTermChange() {
 				this.filterConditions.term =
-					this.filterTerm === "全部" ? null : this.filterTerm;
+					this.filterTerm === this.$t('totalAnalysis.all') ? null : this.filterTerm;
 				this.doFilter();
 			},
 			filterTypeChange() {
@@ -424,7 +430,7 @@
 				// this.filterConditions.type =
 				//     this.filterType === "全部" ? null : this.filterType;
 				console.log(this.filterType)
-				if (this.filterType === "全部") {
+				if (this.filterType === this.$t('totalAnalysis.all')) {
 					this.filterConditions.type = null
 				} else {
 					let res = this.filterData.typeList.find(item => {
@@ -437,11 +443,12 @@
 
 			filterSubjectChange() {
 				this.filterConditions.subject =
-					this.filterSubject === "全部" ? null : this.filterSubject;
+					this.filterSubject === this.$t('totalAnalysis.all') ? null : this.filterSubject;
 				this.doFilter();
 			},
 
 			doFilter() {
+				localStorage.setItem('filterConditions',JSON.stringify(this.filterConditions))
 				// 将条件转换成数组便于渲染
 				this.filterList = this.objToArr(this.filterConditions);
 				// 根据条件过滤所有的测验数据
@@ -480,22 +487,28 @@
 
 			async handleChooseExam(item, index) {
 				this.isLoadingList = true
-				let examSummary = await this.getExamSummary(item)
-				this.$store.commit('clearAnalysis', null)
-				this.$store.dispatch('getAnalysisJson', {
-					code: item.code.replace('Exam-', ''),
-					id: item.id
-				}).then(res => {
-					console.log(res)
-					localStorage.setItem('curExam', JSON.stringify(examSummary))
-					this.isLoadingList = false
-					this.$router.push({
-						path: "/total"
-					});
-				}).catch(err => {
-					this.$Message.error('该评测班级数据获取异常,请稍后再试!')
+				try{
+					let examSummary = await this.getExamSummary(item)
+					this.$store.commit('clearAnalysis', null)
+					this.$store.dispatch('getAnalysisJson', {
+						code: item.code.replace('Exam-', ''),
+						id: item.id
+					}).then(res => {
+						console.log(res)
+						localStorage.setItem('curExam', JSON.stringify(examSummary))
+						this.isLoadingList = false
+						this.$router.push({
+							path: "/total"
+						});
+					}).catch(err => {
+						this.$Message.error(this.$t('totalAnalysis.noData'))
+						this.isLoadingList = false
+					})
+				}catch(e){
 					this.isLoadingList = false
-				})
+					this.$Message.error('API ERROR!')
+				}
+				
 			},
 
 			/* 获取当前点击评测的详情数据 */
@@ -514,7 +527,6 @@
 							},
 							err => {
 								j(err)
-								this.$Message.error('API ERROR!')
 							}
 					)
 				})
@@ -524,11 +536,13 @@
 			if (this.$route.params.tabName) {
 				this.tabName = this.$route.params.tabName;
 			}
+			
+			
 		},
 		computed: {
 			getJoinRate() {
 				return (item) => {
-					return (item.stuCount / item.stuCount).toFixed(2) * 100 + "%";
+					return item.stuCount === 0 ? 0 : (item.stuCount / item.stuCount).toFixed(2) * 100 + "%";
 				};
 			},
 			filterGradeList() {

+ 1 - 1
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/KnowledgeAnalysis/ScoreDetails.vue

@@ -11,7 +11,7 @@
                     <BaseRadar echartsId="knowRadar"></BaseRadar>
                 </div>
             </Col>
-            <Col span="12">
+            <Col span="12"  style="padding: 30px 100px 0 0">
             <!-- 知识点得分详情 -->
                 <!-- <span class="component-title"><span style="font-size:14px;font-weight:bold;margin-left:20px;color:#66cccc">{{$t('totalAnalysis.ka_text2')}}:{{currentPoint}}</span></span> -->
                 <div>

+ 37 - 26
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/ScatterAnalysis/ScatterAnalysis.vue

@@ -94,31 +94,50 @@
                         title: this.$t('totalAnalysis.base_class'),
                         key: 'className',
 						sortable:'custom',
-                        minWidth: 100
+                        minWidth: 60
                     },
                     {
                         title: this.$t('totalAnalysis.base_id'),
-                        key: 'memberId',
+                        key: 'no',
                         sortable: 'custom',
-                        minWidth: 100
-                    },
-                    {
-                        title: this.$t('totalAnalysis.base_score'),
-                        sortable: 'custom',
-                        key: 'score',
-                        minWidth: 100
+                        minWidth: 50
                     },
+					{
+					    title: this.$t('totalAnalysis.sca_chart_text1'),
+					    key: 'scoreRate',
+					    sortable: 'custom',
+					    minWidth: 50
+					},
+					{
+					    title: this.$t('totalAnalysis.sca_table_text6'),
+					    key: 'scatter',
+					    minWidth: 60
+					},
+					{
+					    title: this.$t('totalAnalysis.sca_table_text5'),
+					    sortable: true,
+						renderType: function(h, params) {
+						    return h('span', Number(params.row.x).toFixed(2))
+						},
+					    minWidth: 60
+					},
+                    // {
+                    //     title: this.$t('totalAnalysis.base_score'),
+                    //     sortable: 'custom',
+                    //     key: 'score',
+                    //     minWidth: 60
+                    // },
                     {
                         title: this.$t('totalAnalysis.sca_table_text1'),
                         key: 'trueNum',
                         sortable: 'custom',
-                        minWidth: 100
+                        minWidth: 60
                     },
                     {
                         title: this.$t('totalAnalysis.sca_table_text2'),
                         key: 'falseNum',
                         sortable: 'custom',
-                        minWidth: 100
+                        minWidth: 60
                     },
                     {
                         title: this.$t('totalAnalysis.sca_table_text3'),
@@ -132,19 +151,7 @@
                         key: 'carefulList',
                         renderType: 'renderCareful'
                     },
-                    {
-                        title: this.$t('totalAnalysis.sca_table_text5'),
-                        sortable: true,
-						renderType: function(h, params) {
-						    return h('span', Number(params.row.x).toFixed(2))
-						},
-                        minWidth: 120
-                    },
-                    {
-                        title: this.$t('totalAnalysis.sca_table_text6'),
-                        key: 'scatter',
-                        minWidth: 100
-                    }
+                    
                 ]
             }
         },
@@ -193,6 +200,7 @@
 					analysisJson.scatterKey.forEach((key, index) => {
 						stu.subjects[subjectIndex].scatter[0] = stu.name
 						obj[key] = stu.subjects[subjectIndex].scatter[index]
+						obj.no = stu.no
 					})
 					result.push(obj)
 				})
@@ -204,8 +212,9 @@
             this.$refs.scatterTable.$el.childNodes[1].style.borderRight = '0'
             if (this.getAnalysisJson) {
                 this.tableData = this.renderData(this.getAnalysisJson)
+				console.log(this.tableData)
 				this.originTableData = JSON.parse(JSON.stringify(this.tableData)) 
-                this.classList = ['全部'].concat([...new Set(this.getAnalysisJson.classes.map(item => item.className))]) // 获取班级列表
+                this.classList = [this.$t('totalAnalysis.allClasses')].concat([...new Set(this.getAnalysisJson.classes.map(item => item.className))]) // 获取班级列表
             }
 			
 			this.$EventBus.$off('onSubjectChange')
@@ -217,6 +226,8 @@
 			
 			this.$EventBus.$off('changeClassName')
 			this.$EventBus.$on('changeClassName',val => {
+				console.log('落点选择的班级',val)
+				console.log(this.classList)
 				 this.onClassSelect(this.classList.indexOf(val))
 			})
         },
@@ -234,7 +245,7 @@
                     if (val) {
                         this.tableData = this.renderData(JSON.parse(JSON.stringify(val)) )
 						this.originTableData = JSON.parse(JSON.stringify(this.tableData)) 
-                        this.classList = ['全部'].concat([...new Set(val.classes.map(item => item.className))])
+                        this.classList = [this.$t('totalAnalysis.allClasses')].concat([...new Set(val.classes.map(item => item.className))])
                     }
                 }
 

+ 2 - 2
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/TestAnalysis/TestAnalysis.vue

@@ -26,7 +26,7 @@
 				</div>
 				<Divider />
 				<div class="scatter-table-line">
-					<span>A-</span>
+					<span>A'</span>
 					<span class="scatter-explain"
 						:title="$t('totalAnalysis.ta_text7')">{{$t('totalAnalysis.ta_text7')}}</span>
 					<span>{{A2List.length}}</span>
@@ -48,7 +48,7 @@
 				</div>
 				<Divider />
 				<div class="scatter-table-line">
-					<span>B-</span>
+					<span>B'</span>
 					<span class="scatter-explain"
 						:title="$t('totalAnalysis.ta_text9')">{{$t('totalAnalysis.ta_text9')}}</span>
 					<span>{{B2List.length}}</span>

+ 11 - 6
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/index.less

@@ -108,16 +108,18 @@ body, html, .total-container {
 }
 .total-content {
   .basic-info {
-	  font-size: 12px;
+	  font-size: 14px;
     .info-type {
       padding: 1px 5px;
       color: #fbd103;
       border-radius: 5px;
       border: 1px solid #fbd103;
+	  font-size: 12px;
       vertical-align: super;
     }
     .info-subject {
       padding: 2px 6px;
+	  font-size: 12px;
       color: #eee;
       border-radius: 3px;
       vertical-align: super;
@@ -128,20 +130,23 @@ body, html, .total-container {
       padding: 2px 6px;
       color: #eee;
       border-radius: 3px;
+	  font-size: 12px;
       vertical-align: super;
       margin-left: 10px;
       background: #018b99;
     }
     .info-name {
       color: #fff;
-      font-size: 22px;
+      font-size: 24px;
       margin-left: 10px;
+	  display: inline-block;
+	  margin-bottom: 4px;
       cursor: pointer;
     }
     .info-date-person {
       margin-top: 10px;
       display: flex;
-      color: #9e9e9e;
+      color: #e1e1e1;
       .info-item {
         margin-left: 20px;
         &:first-child {
@@ -158,7 +163,7 @@ body, html, .total-container {
     bottom: 8px;
     right: 40px;
     color: #d1d1d1;
-    font-size: 12px;
+    font-size: 14px;
     .basic-tool-export {
       padding: 5px 10px;
       background: none;
@@ -183,8 +188,7 @@ body, html, .total-container {
   .data-select {
     padding: 25px 0 0 22px;
     color: #9e9e9e;
-    font-size: 14px;
-    font-weight: bold;
+    font-size: 16px;
     .data-select-active {
       color: #fff;
       border-bottom: 3px solid #42beda;
@@ -218,6 +222,7 @@ body, html, .total-container {
 		display: inline-block;
 		margin-right: 20px;
 		padding: 0 8px 2px 8px;
+		font-size: 14px;
 		cursor: pointer;
 	}
 	&-item-active{

+ 12 - 9
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/index.vue

@@ -120,7 +120,7 @@
 			ExportTables,
 			Loading
 		},
-		data() {
+		data(vm) {
 			return {
 				searchValue: '',
 				contentLoading: false,
@@ -143,9 +143,9 @@
 					'normal': '#00ff8a'
 				},
 				nameTransfer: {
-					'regular': '正规考',
-					'simulation': '模拟考',
-					'normal': '正常考'
+					regular: vm.$t('totalAnalysis.ti_text6'),
+					simulation: vm.$t('totalAnalysis.ti_text7'),
+					normal: vm.$t('totalAnalysis.ti_text8')
 				},
 				scrollTopssss: 0,
 				totalAverage: 0,
@@ -185,9 +185,6 @@
 					}, {
 						tableRef: 'entryRateTable',
 						tableName: '进线率统计'
-					}, {
-						tableRef: 'achievementTable',
-						tableName: '预警统计表格'
 					}])
 					this.$router.push({
 						path: '/total'
@@ -377,7 +374,7 @@
 			console.log(this.currentExamItem)
 
 			if (this.getAnalysisJson) {
-				this.classList = ['全部'].concat([...new Set(this.getAnalysisJson.classes.map(item => item
+				this.classList = [this.$t('totalAnalysis.allClasses')].concat([...new Set(this.getAnalysisJson.classes.map(item => item
 					.className))]) // 获取班级列表
 			}
 		},
@@ -388,7 +385,13 @@
 			},
 			getSubjectList() {
 				this.subjectSelectVal = this.$store.state.totalAnalysis.currentSubject
-				return this.$store.state.totalAnalysis.subjectList
+				/* 如果是成绩分析则要加入全科统计栏目 */
+				if(this.dataSelectIndex === '0'){
+					return ['全科',...this.$store.state.totalAnalysis.subjectList] 
+				}else{
+					return this.$store.state.totalAnalysis.subjectList
+				}
+				
 			},
 			getVuexExamList() {
 				return this.$store.state.totalAnalysis.examList

+ 10 - 6
TEAMModelOS/Controllers/Analysis/AnalysisController.cs

@@ -207,6 +207,8 @@ namespace TEAMModelOS.Controllers.Analysis
                 Dictionary<string, double> paperScore = new Dictionary<string, double>();
                 List<KeyValuePair<string, List<KeyValuePair<string, List<string>>>>> subjectScatter = new List<KeyValuePair<string, List<KeyValuePair<string, List<string>>>>>();
                 List<KeyValuePair<string, Dictionary<string, List<double>>>> gscores = new List<KeyValuePair<string, Dictionary<string, List<double>>>>();
+                //声明全科总分
+                double totalAll = 0;
                 foreach (ExamResult examResult in examResults)
                 {
                     (KeyValuePair<string, List<List<string>>> subjectData, KeyValuePair<string, List<KeyValuePair<string, List<double>>>> classSubjectData , Dictionary<string, List<double>> gscore) =DoExerciseScatteres(examResult, paperKey);
@@ -237,6 +239,7 @@ namespace TEAMModelOS.Controllers.Analysis
                     //gpointList.Add("levelKey", DoLevel(examResult, info));
                     valuePairs.Add(gpointList);
                     //获取一张试卷的满分
+                    totalAll += examResult.paper.point.Sum();
                     paperScore.Add(examResult.subjectId, examResult.paper.point.Sum());
                     List<double> StuSubjectTotals = new List<double>();
                     classReses = examResult.classes;
@@ -264,6 +267,7 @@ namespace TEAMModelOS.Controllers.Analysis
                                 if (y.id.Equals(examResult.subjectId))
                                 {
                                     y.score = score;
+                                    y.sRate = Math.Round(examResult.paper.point.Sum() > 0 ? score / examResult.paper.point.Sum(): 0,2);
                                 }
                             });
                         }
@@ -277,6 +281,7 @@ namespace TEAMModelOS.Controllers.Analysis
                                 fieldPoint = fieldStuPerDatas.Where(x => x.Key == examResult.subjectId).SelectMany(va => va.Value).Where(stu => stu.Key == stuid).Select(pi => pi.Value).First()
                             };
                             subject.score = score;
+                            subject.sRate = Math.Round(examResult.paper.point.Sum() > 0 ? score / examResult.paper.point.Sum() : 0, 2);
                             student.subjects.Add(subject);
                         }
                     }
@@ -284,6 +289,7 @@ namespace TEAMModelOS.Controllers.Analysis
                 }
                 foreach (StudentAys student1 in students) {
                     gradeTotal.Add(student1.total);
+                    student1.sRate = totalAll > 0 ? Math.Round(student1.total / totalAll, 2) : 0;
                 }
                 //处理进线分数
                 gradeTotal.Sort((s1, s2) => { return s2.CompareTo(s1); });
@@ -359,7 +365,8 @@ namespace TEAMModelOS.Controllers.Analysis
                             x.name =x.id;
                             x.no = "-";
                         }
-                       
+                        //班级得分率
+                        x.csRate = totalAll > 0 ? Math.Round(totalAverage / totalAll,2) : 0;
                         //标准差
                         powSum += Math.Pow(x.total - totalAverage, 2);
                         //进线人数
@@ -442,7 +449,8 @@ namespace TEAMModelOS.Controllers.Analysis
                             passPercent= passPercent, 
                             passCount= passCount, 
                             average= average ,
-                            name= info.subjects.Where(x => x.id == key).FirstOrDefault().name,
+                            sRate = paperScore[key]> 0 ? Math.Round(average / paperScore[key],2) : 0,
+                            name = info.subjects.Where(x => x.id == key).FirstOrDefault().name,
                             item = classSubjectPaperDatas.Where(subd => subd.Key == key).First().Value.Where(cls => cls.Key == classId).First().Value
                         });
                     }
@@ -1093,10 +1101,6 @@ namespace TEAMModelOS.Controllers.Analysis
             }
             int stuNo = 0;
             exam.studentIds.ForEach(e => {
-               
-                //values.Add(e);
-              
-               
                 List<double> valueKnow = new List<double>();
                 foreach (string know in knowledge) {
                     double anwPoint = 0;

+ 1 - 0
TEAMModelOS/Controllers/Analysis/ClassAys.cs

@@ -31,6 +31,7 @@ namespace TEAMModelOS.Controllers.Analysis
         public string id { get; set; }
         public double passPercent { get; set; }
         public double average { get; set; }
+        public double sRate { get; set; }
         public List<double> item { get; set; }
 
     }

+ 3 - 0
TEAMModelOS/Controllers/Analysis/StudentAys.cs

@@ -19,6 +19,8 @@ namespace TEAMModelOS.Controllers.Analysis
         public string classId { get; set; }
         public string className { get; set; }
         public string gradeId { get; set; }
+        public double csRate { get; set; }
+        public double sRate { get; set; }
        
     }
     public class StudentSubject{
@@ -32,5 +34,6 @@ namespace TEAMModelOS.Controllers.Analysis
         public double score { get; set; }
         public int csort { get; set; }
         public int gsort { get; set; }
+        public double sRate { get; set; }
     }
 }

+ 9 - 9
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -276,7 +276,7 @@ namespace TEAMModelOS.Controllers
             try
             {
                 if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
-                var query = $"select c.id,c.name,c.code,c.period,c.startTime,c.endTime,c.stuCount,c.type,c.progress,c.examType,c.createTime, c.subjects, c.grades, c.scope,c.classes,c.papers from c ";
+                var query = $"select c.id,c.name,c.code,c.period,c.startTime,c.endTime,c.stuCount,c.type,c.progress,c.examType,c.createTime, c.subjects, c.grades, c.scope,c.classes from c ";
                 if (requert.TryGetProperty("classIds", out JsonElement classIds)) {
                     List<string> ids = classIds.ToObject<List<string>>();
                     HashSet<string> strs = new HashSet<string>();
@@ -292,10 +292,10 @@ namespace TEAMModelOS.Controllers
                         strs.Add($"array_contains(c.classes,'{ssr}')");
                     }
                     string ss = string.Join(" or ", strs);
-                    query = $"select c.id,c.name,c.code,c.period,c.startTime,c.endTime,c.stuCount,c.type,c.progress,c.examType,c.createTime, c.subjects, c.grades, c.scope,c.classes,c.papers from c where ({ss})";
+                    query = $"select c.id,c.name,c.code,c.period,c.startTime,c.endTime,c.stuCount,c.type,c.progress,c.examType,c.createTime, c.subjects, c.grades, c.scope,c.classes from c where ({ss})";
                 };
                 var client = _azureCosmos.GetCosmosClient();
-                List<ExamInfo> examInfos = new List<ExamInfo>();                
+                List<ExamInfo> examInfo = new List<ExamInfo>();                
                 await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{code}") }))
                 {
                     using var json = await JsonDocument.ParseAsync(item.ContentStream);
@@ -304,21 +304,21 @@ namespace TEAMModelOS.Controllers
                         foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                         {
                             //obj.TryGetProperty("progress", out JsonElement progress);
-                            examInfos.Add(obj.ToObject<ExamInfo>());
+                            examInfo.Add(obj.ToObject<ExamInfo>());
                         }
                     }
                 }
                 //List<string> examIds = new List<string>();
-                List<ExamResult> examResults = new List<ExamResult>();
+               /* List<ExamResult> examResults = new List<ExamResult>();
                 foreach (ExamInfo info in examInfos) {                    
                     await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamResult>(
                                        queryText: $"select value(c) from c where c.examId  = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamResult-{info.id}") }))
                     {
                         examResults.Add(item);
                     }
-                }
+                }*/
                
-                List<(string id, double scores)> listExamInfo = new List<(string id, double scores)>(); 
+               /* List<(string id, double scores)> listExamInfo = new List<(string id, double scores)>(); 
                 foreach (ExamInfo info in examInfos)
                 {
                     //记录某次考试所有学生得分总分
@@ -326,7 +326,7 @@ namespace TEAMModelOS.Controllers
                     double allScore = 0;
                     int stuCount = 0;
                     foreach (ExamResult examResult in examResults) {
-                        if ("7289f68e-22a1-4b94-96f0-fb4202669fc4" == examResult.examId) {
+                        if (info.id == examResult.examId) {
                             foreach (List<double> sc in examResult.studentScores) {
                                 score += sc.Sum();
                             }
@@ -358,7 +358,7 @@ namespace TEAMModelOS.Controllers
                                         o.classes,
                                         score = listExamInfo.FirstOrDefault(c => c.id == o.id).scores,
                                     }
-               );
+               );*/
                 return Ok(new { examInfo });
             }
             catch (Exception e)