瀏覽代碼

Merge branch 'develop' into cmy/develop-bi

chenmy 2 年之前
父節點
當前提交
72b810529e
共有 32 個文件被更改,包括 1977 次插入70 次删除
  1. 11 1
      TEAMModelBI/Controllers/BISchool/SchoolController.cs
  2. 3 3
      TEAMModelBI/TEAMModelBI.csproj
  3. 40 27
      TEAMModelBI/Tool/CosmosBank/ActivityWay.cs
  4. 162 1
      TEAMModelOS.SDK/Models/Cosmos/BI/StatsInfo.cs
  5. 1 0
      TEAMModelOS/ClientApp/package.json
  6. 1 1
      TEAMModelOS/ClientApp/src/components/dashboard/art/BaseArtScatter.vue
  7. 3 2
      TEAMModelOS/ClientApp/src/components/dashboard/art/BaseClassLineBar.vue
  8. 2 3
      TEAMModelOS/ClientApp/src/store/module/artDashboard.js
  9. 8 2
      TEAMModelOS/ClientApp/src/view/areaArtExam/Mgt.vue
  10. 1 1
      TEAMModelOS/ClientApp/src/view/areaMgmt/AreaData.vue
  11. 1 1
      TEAMModelOS/ClientApp/src/view/areaMgmt/SchoolComp.vue
  12. 5 1
      TEAMModelOS/ClientApp/src/view/artexam/Mgt.vue
  13. 14 3
      TEAMModelOS/ClientApp/src/view/dashboard/fiveEdu/FiveEdu.vue
  14. 二進制
      TEAMModelOS/ClientApp/src/view/dashboard/moral/1.jpg
  15. 二進制
      TEAMModelOS/ClientApp/src/view/dashboard/moral/2.jpg
  16. 二進制
      TEAMModelOS/ClientApp/src/view/dashboard/moral/3.jpg
  17. 二進制
      TEAMModelOS/ClientApp/src/view/dashboard/moral/4.jpg
  18. 二進制
      TEAMModelOS/ClientApp/src/view/dashboard/moral/5.jpg
  19. 二進制
      TEAMModelOS/ClientApp/src/view/dashboard/moral/6.jpg
  20. 74 0
      TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseCarousel.vue
  21. 258 0
      TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseExamLine.vue
  22. 123 0
      TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseRadar.vue
  23. 464 0
      TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseScoreBar.vue
  24. 148 0
      TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseScoreLine.vue
  25. 100 0
      TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseScorePie.vue
  26. 146 0
      TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseSubLine.vue
  27. 115 0
      TEAMModelOS/ClientApp/src/view/dashboard/moral/MoralDash.less
  28. 238 0
      TEAMModelOS/ClientApp/src/view/dashboard/moral/MoralDash.vue
  29. 23 18
      TEAMModelOS/ClientApp/src/view/dashboard/study/StudyDash.vue
  30. 10 2
      TEAMModelOS/Controllers/School/ArtReviewController.cs
  31. 21 0
      TEAMModelOS/Controllers/XTest/TestController.cs
  32. 5 4
      TEAMModelOS/appsettings.json

+ 11 - 1
TEAMModelBI/Controllers/BISchool/SchoolController.cs

@@ -1502,6 +1502,9 @@ namespace TEAMModelBI.Controllers.BISchool
                     case "admin":
                         schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}", "admin");
                         break;
+                    case "sales":
+                        schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}", "sales");
+                        break;
                     default:
                         schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
                         break;
@@ -1595,7 +1598,7 @@ namespace TEAMModelBI.Controllers.BISchool
                             scSql = BICommonWay.ManyScSql("c.school", schoolIds);
                             break;
                         case "sales":
-                            schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}", isMany: true);
+                            schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}", "sales");
                             scSql = BICommonWay.ManyScSql("c.school", schoolIds);
                             break;
                         default:
@@ -1689,6 +1692,10 @@ namespace TEAMModelBI.Controllers.BISchool
                     case "admin":
                         schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}", "admin");
                         break;
+                    case "sales":
+                        schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}", "sales");
+                        //scSql = BICommonWay.ManyScSql("c.school", schoolIds);
+                        break;
                     default:
                         schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
                         break;
@@ -1841,6 +1848,9 @@ namespace TEAMModelBI.Controllers.BISchool
                     case "admin":
                         schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}", "admin");
                         break;
+                    case "sales":
+                        schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}", "sales");
+                        break;
                     default:
                         schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
                         break;

+ 3 - 3
TEAMModelBI/TEAMModelBI.csproj

@@ -59,9 +59,9 @@
 		<SpaRoot>ClientApp\</SpaRoot>
 		<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
 		<UserSecretsId>078b5d89-7d90-4f6a-88fc-7d96025990a8</UserSecretsId>
-		<Version>1.2210.28</Version>
-		<AssemblyVersion>1.2210.28.2</AssemblyVersion>
-		<FileVersion>1.2210.28.2</FileVersion>
+		<Version>1.2210.31</Version>
+		<AssemblyVersion>1.2210.31.1</AssemblyVersion>
+		<FileVersion>1.2210.31.1</FileVersion>
 		<Description>TEAMModelBI(BI)</Description>
 		<PackageReleaseNotes>BI版本说明版本切换标记2022000908</PackageReleaseNotes>
 		<PackageId>TEAMModelBI</PackageId>

+ 40 - 27
TEAMModelBI/Tool/CosmosBank/ActivityWay.cs

@@ -19,45 +19,49 @@ namespace TEAMModelBI.Tool.CosmosBank
         public async static Task<int> GetAll(CosmosClient cosmosClient, List<string> scIds = null, List<string> tecIds = null)
         {
             int totals = 0;
-            string sqlTxt = "select count(c.id) as totals from c";
-            foreach (string type in types)
+            try
             {
-                if (scIds.Count > 0)
+                string sqlTxt = "select count(c.id) as totals from c";
+                foreach (string type in types)
                 {
-                    foreach (string sc in scIds)
+                    if (scIds.Count > 0)
                     {
-                        await foreach (var itemTeac in cosmosClient.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{type}-{sc}") }))
+                        foreach (string sc in scIds)
                         {
-                            using var json = await JsonDocument.ParseAsync(itemTeac.ContentStream);
-                            if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetInt32() > 0)
+                            await foreach (var itemTeac in cosmosClient.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{type}-{sc}") }))
                             {
-                                foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                                using var json = await JsonDocument.ParseAsync(itemTeac.ContentStream);
+                                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetInt32() > 0)
                                 {
-                                    totals += obj.GetProperty("totals").GetInt32();
+                                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                                    {
+                                        totals += obj.GetProperty("totals").GetInt32();
+                                    }
                                 }
                             }
                         }
                     }
-                }
 
-                if (tecIds.Count > 0)
-                {
-                    foreach (string sc in scIds)
+                    if (tecIds.Count > 0)
                     {
-                        await foreach (var itemTeac in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{type}-{sc}") }))
+                        foreach (string sc in scIds)
                         {
-                            using var json = await JsonDocument.ParseAsync(itemTeac.ContentStream);
-                            if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetInt32() > 0)
+                            await foreach (var itemTeac in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{type}-{sc}") }))
                             {
-                                foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                                using var json = await JsonDocument.ParseAsync(itemTeac.ContentStream);
+                                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetInt32() > 0)
                                 {
-                                    totals += obj.GetProperty("totals").GetInt32();
+                                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                                    {
+                                        totals += obj.GetProperty("totals").GetInt32();
+                                    }
                                 }
                             }
                         }
                     }
                 }
             }
+            catch { }
             return totals;
         }
 
@@ -72,14 +76,19 @@ namespace TEAMModelBI.Tool.CosmosBank
         public static async Task<int> GetCnt(CosmosClient cosmosClient, string container = "Common", string condSql = null, string code = null) 
         {
             int total = 0;
-            foreach (string type in types)
+            try
             {
-                string sqlTxt = $"select value(count(c.id)) from c where c.pk='{type}' {condSql}";
-                await foreach (var cnt in cosmosClient.GetContainer("TEAMModelOS", container).GetItemQueryIterator<int>(queryText: sqlTxt, requestOptions: string.IsNullOrEmpty($"{code}") ? new QueryRequestOptions() { } : new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") })) 
+                foreach (string type in types)
                 {
-                    total += cnt;
+                    string sqlTxt = $"select value(count(c.id)) from c where c.pk='{type}' {condSql}";
+                    await foreach (var cnt in cosmosClient.GetContainer("TEAMModelOS", container).GetItemQueryIterator<int>(queryText: sqlTxt, requestOptions: string.IsNullOrEmpty($"{code}") ? new QueryRequestOptions() { } : new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
+                    {
+                        total += cnt;
+                    }
                 }
             }
+            catch { }
+
             return total;
         }
 
@@ -94,17 +103,21 @@ namespace TEAMModelBI.Tool.CosmosBank
         public static async Task<int> GetCnt(CosmosClient cosmosClient, List<string> containers, string condSql = null, string code = null)
         {
             int total = 0;
-            foreach (var container in containers)
+            try
             {
-                foreach (string type in types)
+                foreach (var container in containers)
                 {
-                    string sqlTxt = $"select value(count(c.id)) from c where c.pk='{type}' {condSql}";
-                    await foreach (var cnt in cosmosClient.GetContainer("TEAMModelOS", container).GetItemQueryIterator<int>(queryText: sqlTxt, requestOptions: string.IsNullOrEmpty($"{code}") ? new QueryRequestOptions() { } : new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
+                    foreach (string type in types)
                     {
-                        total += cnt;
+                        string sqlTxt = $"select value(count(c.id)) from c where c.pk='{type}' {condSql}";
+                        await foreach (var cnt in cosmosClient.GetContainer("TEAMModelOS", container).GetItemQueryIterator<int>(queryText: sqlTxt, requestOptions: string.IsNullOrEmpty($"{code}") ? new QueryRequestOptions() { } : new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
+                        {
+                            total += cnt;
+                        }
                     }
                 }
             }
+            catch { }
             return total;
         }
 

+ 162 - 1
TEAMModelOS.SDK/Models/Cosmos/BI/StatsInfo.cs

@@ -8,9 +8,170 @@ namespace TEAMModelOS.SDK.Models.Cosmos.BI
 {
     public class StatsInfo : CosmosEntity
     {
+        //id  学校id
         //pk   Stats
-        //code   Stats-hbcn  Stats-学校id   Stats-学区id
+        //code Stats
+        //code   Stats-hbcn  Stats-学校id   Stats-学区id 暂未启动
+        public StatsInfo()
+        {
+            pk = "Stats";
+        }
 
+        /// <summary>
+        /// 学校头像
+        /// </summary>
+        public string picture { get; set; }
 
+        /// <summary>
+        /// 学校名称
+        /// </summary>
+        public string name { get; set; }
+
+        /// <summary>
+        /// 教师总数
+        /// </summary>
+        public int tch { get; set; }
+
+        /// <summary>
+        /// 当天新增教师
+        /// </summary>
+        public int dayTch { get; set; }
+
+        /// <summary>
+        /// 本周新增教师
+        /// </summary>
+        public int weekTch { get; set; }
+
+        /// <summary>
+        /// 本月新增教师
+        /// </summary>
+        public int monthTch { get; set; }
+
+        /// <summary>
+        /// 学生总数
+        /// </summary>
+        public int stu { get; set; }
+
+        /// <summary>
+        /// 当天新增学生
+        /// </summary>
+        public int dayStu { get; set; }
+
+        /// <summary>
+        /// 本周新增学生
+        /// </summary>
+        public int weekStu { get; set; }
+
+        /// <summary>
+        /// 本月新增学生
+        /// </summary>
+        public int monthStu { get; set; }
+
+        /// <summary>
+        /// 教室数
+        /// </summary>
+        public int room { get; set; }
+
+        /// <summary>
+        /// 智慧教室
+        /// </summary>
+        public int witRoom { get; set; }
+
+        /// <summary>
+        /// 空间
+        /// </summary>
+        public int size { get; set; }
+
+        /// <summary>
+        /// 学校创建时间
+        /// </summary>
+        public long scCreateDte { get; set; }
+
+        /// <summary>
+        /// 学校统计数据更新时间
+        /// </summary>
+        public long upDate { get; set; }
+
+        public LessonStats lesson { get; set; }
     }
+
+    /// <summary>
+    /// 课例
+    /// </summary>
+    public class LessonStats 
+    {
+        /// <summary>
+        /// 开课数
+        /// </summary>
+        public int open { get; set; }
+
+        /// <summary>
+        /// 课例
+        /// </summary>
+        public int less { get; set; }
+
+        /// <summary>
+        /// 昨天的课例数
+        /// </summary>
+        public int lastDay { get; set; }
+
+        /// <summary>
+        /// 今天课例
+        /// </summary>
+        public int day { get; set; }
+
+        /// <summary>
+        /// 上周课例
+        /// </summary>
+        public int lastWeek { get; set; }
+
+        /// <summary>
+        /// 本周课例
+        /// </summary>
+        public int week { get; set; }
+
+        /// <summary>
+        /// 上学期
+        /// </summary>
+        public int lastTerm { get; set; }
+
+        /// <summary>
+        /// 本学期
+        /// </summary>
+        public int term { get; set; }
+
+        /// <summary>
+        /// 昨天互动次数
+        /// </summary>
+        public int lastDayInter { get; set; }
+
+        /// <summary>
+        /// 今天的互动次数
+        /// </summary>
+        public int dayInter { get; set; }
+
+        /// <summary>
+        /// 上个月互动
+        /// </summary>
+        public int lastMonthInter { get; set; }
+
+        /// <summary>
+        /// 本月互动
+        /// </summary>
+        public int monthInter { get; set; }
+
+        /// <summary>
+        /// 去年每天的数据  366天
+        /// </summary>
+        public List<double> LastYear { get; set; }
+
+        /// <summary>
+        /// 今年每天的数据 366天
+        /// </summary>
+        public List<double> year { get; set; }
+    } 
+
+
+
+
 }

+ 1 - 0
TEAMModelOS/ClientApp/package.json

@@ -59,6 +59,7 @@
     "vue-apexcharts": "^1.6.0",
     "vue-audio-native": "^0.1.41",
     "vue-b2wordcloud": "^1.0.5",
+    "vue-carousel-3d": "^1.0.1",
     "vue-clipboard2": "^0.3.3",
     "vue-count-to": "^1.0.13",
     "vue-lazyload": "^1.3.3",

+ 1 - 1
TEAMModelOS/ClientApp/src/components/dashboard/art/BaseArtScatter.vue

@@ -302,7 +302,7 @@ export default {
           this.$nextTick(() => {
             let analysisJson = this.$store.state.artDashboard.artAnalysisJson
             let scatterArr = n.map(student => [student.sta, (student.pass * 100).toFixed(2)])
-            this.doRender(scatterArr, analysisJson.students)
+            this.doRender(scatterArr, n)
           })
         }
       }

+ 3 - 2
TEAMModelOS/ClientApp/src/components/dashboard/art/BaseClassLineBar.vue

@@ -242,8 +242,9 @@ export default {
         if (n) {
           let artAnalysisJson = this.$store.state.artDashboard.artAnalysisJson
           this.$nextTick(() => {
-            let analysisJson = n
-            let classDatas = artAnalysisJson.cInfo.map(classInfo => {
+            let curGradeId = n
+            console.log(curGradeId)
+            let classDatas = artAnalysisJson.cInfo.filter(i => i.gradeId == curGradeId).map(classInfo => {
               return {
                 className: classInfo.name,
                 average: classInfo.score,

+ 2 - 3
TEAMModelOS/ClientApp/src/store/module/artDashboard.js

@@ -23,17 +23,16 @@ export default {
                     })
                 })
             })
-            console.error(result)
             state.knowledges = result
             state.scatterStuArr = value.students
         },
         setGradeId: (state, value) => {
             state.curGradeId = value
-            state.scatterStuArr = state.artAnalysisJson.students.filter(i => i.gradeId === value)
+            state.scatterStuArr = state.artAnalysisJson.students.filter(i => i.gradeId == value)
         },
         setClassId: (state, value) => {
             state.curClassId = value
-            state.scatterStuArr = state.artAnalysisJson.students.filter(i => i.classId === value)
+            state.scatterStuArr = state.artAnalysisJson.students.filter(i => i.classId === value && i.gradeId == state.curGradeId)
         },
         setAllStus: (state, value) => {
             state.scatterStuArr = state.artAnalysisJson.students

+ 8 - 2
TEAMModelOS/ClientApp/src/view/areaArtExam/Mgt.vue

@@ -14,9 +14,13 @@
                 <div style="height:calc(100% - 50px)">
                     <vuescroll>
                         <div :class="['art-item', curIndex == index ? 'art-item-active' : '']" v-for="(item,index) in artList" :key="item.id" @click="selectArt(index)">
-                            <p class="art-name">{{item.name}}</p>
+                            <p class="art-name">
+                                {{item.name}}
+                                <Tag v-if="item.endTime > serverTime" color="success">进行中</Tag>
+                                <Tag v-else color="error">已结束</Tag>
+                            </p>
                             <p class="art-date">
-                                <Icon type="md-time" size="16" />{{$jsFn.dateFormat(item.startTime)}}-{{$jsFn.dateFormat(item.endTime)}}
+                                <Icon type="md-time" size="16" />{{$jsFn.timeFormat(item.startTime)}}-{{$jsFn.timeFormat(item.endTime)}}
                             </p>
                         </div>
                         <EmptyData v-show="!artList.length" :top="100"></EmptyData>
@@ -72,6 +76,7 @@ export default {
     },
     data() {
         return {
+            serverTime: 0,
             hasPublish: true,
             schoolId: '',
             schoolList: [],
@@ -303,6 +308,7 @@ export default {
         },
     },
     created() {
+        this.serverTime = localStorage.getItem('serverTime') || new Date().getTime()
         this.getAreaSchoolList()
         this.getAreaSetting()
     },

+ 1 - 1
TEAMModelOS/ClientApp/src/view/areaMgmt/AreaData.vue

@@ -426,7 +426,7 @@ export default {
         toSchoolDetail(index) {
             this.$router.push({
                 name: "schoolDetail",
-                params: this.schoolList[index]
+                params: this.schoolListShow[index]
             })
         },
         getAreaData() {

+ 1 - 1
TEAMModelOS/ClientApp/src/view/areaMgmt/SchoolComp.vue

@@ -72,7 +72,7 @@ export default {
                 },
                 yAxis: {
                     type: 'value',
-                    name: this.$t('td.td5')
+                    name: this.$t('unit.text7')
                 },
                 series: [
                     {

+ 5 - 1
TEAMModelOS/ClientApp/src/view/artexam/Mgt.vue

@@ -18,9 +18,11 @@
                                 {{item.name}}
                                 <Tag v-if="item.owner === 'area'" color="primary">区级</Tag>
                                 <Tag v-if="!item.classes.length" color="warning">待发布</Tag>
+                                <Tag v-else-if="item.endTime > serverTime" color="success">进行中</Tag>
+                                <Tag v-else color="error">已结束</Tag>
                             </p>
                             <p class="art-date">
-                                <Icon type="md-time" size="16" />{{$jsFn.dateFormat(item.startTime)}}-{{$jsFn.dateFormat(item.endTime)}}
+                                <Icon type="md-time" size="16" />{{$jsFn.timeFormat(item.startTime)}}-{{$jsFn.timeFormat(item.endTime)}}
                             </p>
                         </div>
                         <EmptyData v-show="!artList.length" :top="100"></EmptyData>
@@ -92,6 +94,7 @@ export default {
     },
     data() {
         return {
+            serverTime:0,
             classes: [],
             examInfoList: [],
             btnLoading: false,
@@ -575,6 +578,7 @@ export default {
         },
     },
     created() {
+        this.serverTime = localStorage.getItem('serverTime') || new Date().getTime()
         this.getAreaSetting()
     },
     watch: {

+ 14 - 3
TEAMModelOS/ClientApp/src/view/dashboard/fiveEdu/FiveEdu.vue

@@ -172,6 +172,7 @@
         </div>
 
         <StudyDash v-else-if="activeMenuId === 'study'"></StudyDash>
+        <MoralDash v-else-if="activeMenuId === 'moral'"></MoralDash>
       </div>
     </div>
   </div>
@@ -189,6 +190,7 @@ import BaseCircle from '@/components/dashboard/student/BaseCircle'
 import StudentDetails from '../Student'
 import BaseProgressBar from '@/components/dashboard/student/BaseProgressBar'
 import StudyDash from '../study/StudyDash'
+import MoralDash from '../moral/MoralDash'
 export default {
   data() {
     return {
@@ -345,6 +347,7 @@ export default {
   },
   components: {
     StudyDash,
+    MoralDash,
     countTo,
     StudentDetails,
     BaseRateLine,
@@ -375,7 +378,11 @@ export default {
     onMenuClick(menu) {
       this.activeMenuId = menu.id
       if (menu.id === 'moral') {
-        window.open('https://paas-admin.xydqq.cn/GkI043vXpK9sat5yDW008oaWt9yZ1dwIIq7rdiUywbU4HgI656W2cIbzOWRzoI93vzv82l28DyQKxVVd9qPqFkLLmrlCkIvDlWecschool-datawuhZVGb2K8KM5hlGfU0123tKhKd6b5f84EPUOcszar3ltNpImTPa8BeQtVbcuUtdWUL0zmRaUJRHOlYRVbDofmn9K7XTNwf4Q9mh')
+        if (this.isTestSite) {
+
+        } else {
+          window.open('https://paas-admin.xydqq.cn/GkI043vXpK9sat5yDW008oaWt9yZ1dwIIq7rdiUywbU4HgI656W2cIbzOWRzoI93vzv82l28DyQKxVVd9qPqFkLLmrlCkIvDlWecschool-datawuhZVGb2K8KM5hlGfU0123tKhKd6b5f84EPUOcszar3ltNpImTPa8BeQtVbcuUtdWUL0zmRaUJRHOlYRVbDofmn9K7XTNwf4Q9mh')
+        }
       } else if (menu.id === 'study') {
         // window.open('https://np3mzo.axshare.com/#id=p2g0pj&p=%E6%99%BA%E8%82%B2%E7%9C%8B%E6%9D%BF%EF%BC%88%E6%A0%A1%E7%BA%A7%EF%BC%89')
       } else if (menu.id === 'all') {
@@ -390,7 +397,7 @@ export default {
       }
     },
     goStudent() {
-      this.isAll = false
+      this.$router.push('/stuDetails')
     },
     goBack() {
       this.$tools.exitFullscreen()
@@ -418,7 +425,11 @@ export default {
         periodName: store_user.curPeriod.name,
         curSemester: semesterRange.name
       }
-    }
+    },
+    /* 判断是否为测试站 */
+    isTestSite() {
+      return window.location.host.includes('test.teammodel')
+    },
   }
 }
 </script>

二進制
TEAMModelOS/ClientApp/src/view/dashboard/moral/1.jpg


二進制
TEAMModelOS/ClientApp/src/view/dashboard/moral/2.jpg


二進制
TEAMModelOS/ClientApp/src/view/dashboard/moral/3.jpg


二進制
TEAMModelOS/ClientApp/src/view/dashboard/moral/4.jpg


二進制
TEAMModelOS/ClientApp/src/view/dashboard/moral/5.jpg


二進制
TEAMModelOS/ClientApp/src/view/dashboard/moral/6.jpg


+ 74 - 0
TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseCarousel.vue

@@ -0,0 +1,74 @@
+<template>
+  <div class="moral-carousel-container">
+    <carousel-3d :autoplay=" true" :autoplayTimeout="3000" :height="240" :width="380" :space="180" controlsVisible>
+      <slide v-for="(slide, i) in slides" :index="i" :key="i">
+        <template slot-scope="{ index, isCurrent, leftIndex, rightIndex }">
+          <img :data-index="index" :class="{ current: isCurrent, onLeft: (leftIndex >= 0), onRight: (rightIndex >= 0) }" :src="slide.src">
+        </template>
+      </slide>
+    </carousel-3d>
+    <p class="title">喜迎二十大 · 争做好队员</p>
+  </div>
+
+</template>
+
+<script>
+import { Carousel3d, Slide } from 'vue-carousel-3d';
+export default {
+  components: {
+    Carousel3d,
+    Slide
+  },
+  data() {
+    return {
+      slides: [
+        {
+          src: require('./1.jpg')
+        },
+        {
+          src: require('./2.jpg')
+        },
+        {
+          src: require('./3.jpg')
+        },
+        {
+          src: require('./4.jpg')
+        },
+        {
+          src: require('./5.jpg')
+        },
+        {
+          src: require('./6.jpg')
+        },
+      ]
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.moral-carousel-container {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+
+  .title {
+    font-size: 14px;
+    color: #32c5e9 !important;
+  }
+  .carousel-3d-slide {
+    border-radius: 5px;
+
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+
+  .carousel-3d-controls a span {
+    color: rgb(55, 149, 236) !important;
+  }
+}
+</style>

File diff suppressed because it is too large
+ 258 - 0
TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseExamLine.vue


+ 123 - 0
TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseRadar.vue

@@ -0,0 +1,123 @@
+<template>
+  <div id="studyRadar" class="art-echart"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    }
+  },
+  methods: {
+    doRender() {
+      let myChart = this.$echarts.init(document.getElementById('studyRadar'))
+      var dataname = ['记忆', '理解', '应用', '创造', '评价', '分析']
+      var datamax = [20, 20, 20, 20, 20, 20]
+      var datavaule = [10, 16, 20, 15, 12, 18]
+
+      var indicator = []
+      for (var i = 0; i < dataname.length; i++) {
+        indicator.push({
+          name: dataname[i],
+          max: datamax[i],
+        })
+      }
+      let option = {
+        tooltip: {
+          show: false,
+          trigger: "item",
+        },
+        radar: {
+          center: ["50%", "50%"],
+          radius: "90%",
+          startAngle: 240,
+          splitNumber: 5,
+          splitArea: {
+            areaStyle: {
+              color: [
+                'rgba(0,96,208, 0.1)', 'rgba(0,96,208, 0.2)',
+                'rgba(0,96,208, 0.4)', 'rgba(0,96,208, 0.6)',
+                'rgba(0,96,208, 0.8)', 'rgba(0,96,208, 1)'
+              ].reverse()
+            }
+          },
+          axisLabel: {
+            show: false,
+          },
+          axisLine: {
+            show: true,
+            lineStyle: {
+              color: "transparent"
+            }
+          },
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: "transparent"
+            }
+          },
+          name: {
+            textStyle: {
+              color: '#fff',
+              fontSize: '12',
+              padding: 10
+            }
+          },
+          indicator: indicator
+        },
+
+        series: [{
+          type: "radar",
+          symbol: "circle",
+          symbolSize: 7,
+          areaStyle: {
+            normal: {
+              color: 'rgba(170, 216, 255, 0.2)',
+            }
+          },
+
+          itemStyle: {
+            color: '#84E1FF',
+            borderColor: '#00A7FE',
+            borderWidth: 1,
+          },
+          lineStyle: {
+            normal: {
+              color: "#00A7FE",
+              width: 2
+            }
+          },
+          data: [datavaule]
+        }]
+      };
+      myChart.clear()
+      myChart.setOption(option)
+      window.addEventListener('resize', function () {
+        myChart.resize()
+      })
+
+    }
+  },
+  mounted() {
+    this.doRender()
+  },
+  //   watch: {
+  //     '$store.state.dashboard.artDashboard': {
+  //       deep: true,
+  //       immediate: true,
+  //       handler(n, o) {
+
+  //       }
+  //     }
+  //   }
+}
+</script>
+
+<style>
+.art-echart {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 464 - 0
TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseScoreBar.vue

@@ -0,0 +1,464 @@
+<template>
+  <div id="MoralScoreBar" class="art-echart"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    }
+  },
+  methods: {
+    doRender() {
+      let myChart = this.$echarts.init(document.getElementById('MoralScoreBar'))
+      var yList = [1651, 4051, 1332, 406];
+      var colors = [
+        {
+          type: 'linear',
+          x: 0,
+          x2: 1,
+          y: 0,
+          y2: 0,
+          colorStops: [
+            {
+              offset: 0,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#11A6D0',
+            },
+            {
+              offset: 1,
+              color: '#11A6D0',
+            },
+            {
+              offset: 0,
+              color: '#83bac9',
+            },
+            {
+              offset: 0,
+              color: 'rgba(17,166,208,0.3)',
+            },
+          ],
+        },
+        {
+          type: 'linear',
+          x: 0,
+          x2: 1,
+          y: 0,
+          y2: 0,
+          colorStops: [
+            {
+              offset: 0,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#11A6D0',
+            },
+            {
+              offset: 1,
+              color: '#11A6D0',
+            },
+            {
+              offset: 0,
+              color: '#83bac9',
+            },
+            {
+              offset: 0,
+              color: 'rgba(17,166,208,0.3)',
+            },
+          ],
+        },
+        {
+          type: 'linear',
+          x: 0,
+          x2: 1,
+          y: 0,
+          y2: 0,
+          colorStops: [
+            {
+              offset: 0,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#11A6D0',
+            },
+            {
+              offset: 1,
+              color: '#11A6D0',
+            },
+            {
+              offset: 0,
+              color: '#83bac9',
+            },
+            {
+              offset: 0,
+              color: 'rgba(17,166,208,0.3)',
+            },
+          ],
+        },
+        {
+          type: 'linear',
+          x: 0,
+          x2: 1,
+          y: 0,
+          y2: 0,
+          colorStops: [
+            {
+              offset: 0,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#11A6D0',
+            },
+            {
+              offset: 1,
+              color: '#11A6D0',
+            },
+            {
+              offset: 0,
+              color: '#83bac9',
+            },
+            {
+              offset: 0,
+              color: 'rgba(17,166,208,0.3)',
+            },
+          ],
+        },
+        {
+          type: 'linear',
+          x: 0,
+          x2: 1,
+          y: 0,
+          y2: 0,
+          colorStops: [
+            {
+              offset: 0,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#11A6D0',
+            },
+            {
+              offset: 1,
+              color: '#11A6D0',
+            },
+            {
+              offset: 0,
+              color: '#83bac9',
+            },
+            {
+              offset: 0,
+              color: 'rgba(17,166,208,0.3)',
+            },
+          ],
+        },
+        {
+          type: 'linear',
+          x: 0,
+          x2: 1,
+          y: 0,
+          y2: 0,
+          colorStops: [
+            {
+              offset: 0,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#11A6D0',
+            },
+            {
+              offset: 1,
+              color: '#11A6D0',
+            },
+            {
+              offset: 0,
+              color: '#83bac9',
+            },
+            {
+              offset: 0,
+              color: 'rgba(17,166,208,0.3)',
+            },
+          ],
+        },
+        {
+          type: 'linear',
+          x: 0,
+          x2: 1,
+          y: 0,
+          y2: 0,
+          colorStops: [
+            {
+              offset: 0,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#11A6D0',
+            },
+            {
+              offset: 1,
+              color: '#11A6D0',
+            },
+            {
+              offset: 0,
+              color: '#83bac9',
+            },
+            {
+              offset: 0,
+              color: 'rgba(17,166,208,0.3)',
+            },
+          ],
+        },
+        {
+          type: 'linear',
+          x: 0,
+          x2: 1,
+          y: 0,
+          y2: 0,
+          colorStops: [
+            {
+              offset: 0,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#11A6D0',
+            },
+            {
+              offset: 1,
+              color: '#11A6D0',
+            },
+            {
+              offset: 0,
+              color: '#83bac9',
+            },
+            {
+              offset: 0,
+              color: 'rgba(17,166,208,0.3)',
+            },
+          ],
+        },
+        {
+          type: 'linear',
+          x: 0,
+          x2: 1,
+          y: 0,
+          y2: 0,
+          colorStops: [
+            {
+              offset: 0,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#00FFFF',
+            },
+            {
+              offset: 0.5,
+              color: '#11A6D0',
+            },
+            {
+              offset: 1,
+              color: '#11A6D0',
+            },
+            {
+              offset: 0,
+              color: '#83bac9',
+            },
+            {
+              offset: 0,
+              color: 'rgba(17,166,208,0.3)',
+            },
+          ],
+        },
+      ];
+      let option = {
+        grid: {
+          left: '10%',
+          right: '3%',
+          top: '16%',
+          bottom: '15%',
+        },
+        xAxis: {
+          nameTextStyle: {
+            color: '#00dcf1',
+            padding: [0, 0, 0, 20],
+          },
+          data: ['优秀', '良好', '合格', '待合格'],
+          show: true,
+          type: 'category',
+          axisLabel: {
+            // rotate: -30, // 设置文字旋转
+            fontSize: 12,
+            lineHeight: 24,
+            fontFamily: 'siyuan',
+            // fontStyle: 'italic', // 设置文字斜体
+            textStyle: {
+              //改变刻度字体样式
+              color: '#fff',
+            },
+          },
+          axisTick: {
+            show: false,
+          },
+        },
+        yAxis: {
+          name: '单位:人',
+          nameTextStyle: {
+            fontSize: 12,
+            color: '#fff',
+          },
+          show: true,
+          splitNumber: 4,
+          splitLine: {
+            show: true,
+            lineStyle: {
+              type: 'dashed',
+              color: 'rgba(255,255,255,0.2)',
+            },
+          },
+          axisLabel: {
+            color: '#fff',
+          },
+
+          axisTick: {
+            //y轴刻度线
+            show: false,
+          },
+          axisLine: {
+            //y轴
+            show: false,
+          },
+        },
+        series: [
+          {
+            type: 'bar',
+            barWidth: '40',
+            showBackground: true,
+            backgroundStyle: {
+              color: 'none',
+            },
+            itemStyle: {
+              normal: {
+                color: function (params) {
+                  //console.log(params)
+                  return colors[params.dataIndex % 7];
+                },
+              },
+            },
+            label: {
+              show: true,
+              position: [20, -25],
+              color: '#fff',
+              fontSize: 12,
+              fontStyle: 'bold',
+              align: 'center',
+            },
+
+            data: yList,
+          },
+          {
+            z: 2,
+            type: 'pictorialBar',
+            data: yList,
+            symbol: 'diamond',
+            symbolOffset: [0, '50%'],
+            symbolSize: [40, 10],
+            itemStyle: {
+              normal: {
+                color: function (params) {
+                  return colors[params.dataIndex % 7];
+                },
+              },
+            },
+          },
+          {
+            z: 3,
+            type: 'pictorialBar',
+            symbolPosition: 'end',
+            data: yList,
+            symbol: 'diamond',
+            symbolOffset: [0, '-50%'],
+            symbolSize: [40, 40 * 0.25],
+            itemStyle: {
+              normal: {
+                borderWidth: 0,
+                color: function (params) {
+                  return colors[params.dataIndex % 7].colorStops[0].color;
+                },
+              },
+            },
+          },
+        ],
+      };
+
+      myChart.clear()
+      myChart.setOption(option)
+      window.addEventListener('resize', function () {
+        myChart.resize()
+      })
+
+    }
+  },
+  mounted() {
+    this.doRender()
+  },
+  //   watch: {
+  //     '$store.state.dashboard.artDashboard': {
+  //       deep: true,
+  //       immediate: true,
+  //       handler(n, o) {
+
+  //       }
+  //     }
+  //   }
+}
+</script>
+
+<style>
+.art-echart {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 148 - 0
TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseScoreLine.vue

@@ -0,0 +1,148 @@
+<template>
+  <div id="moralScoreLine" class="art-echart" style="height:120px;"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    }
+  },
+  methods: {
+    doRender() {
+      let myChart = this.$echarts.init(document.getElementById('moralScoreLine'))
+      let option = {
+        color: ['#fd5151', '#1370fb'],
+        tooltip: {},
+        grid: {
+          height: '30%',
+          top: '0',
+        },
+        xAxis: [
+          {
+            type: 'value',
+            min: -100,
+            max: 100,
+            axisTick: {
+              show: false
+            },
+            axisLine: {
+              show: false
+            },
+            axisLabel: {
+              show: false
+            },
+            splitLine: {
+              show: false
+            }
+          }
+        ],
+        yAxis: [
+          {
+            type: 'category',
+            inverse: false,
+            data: '',
+            axisTick: {
+              show: false
+            },
+            axisLine: {
+              show: false
+            },
+            axisLabel: {
+              show: false,
+              color: '#fff',
+              fontSize: 14,
+              // 右对齐
+              align: 'left',
+              padding: [0, -380, 0, 0],
+              verticalAlign: 'bottom',
+              lineHeight: 58,
+            },
+            data: ['']
+          }
+        ],
+        series: [
+
+          {
+            name: '减分',
+            type: 'bar',
+            stack: '总量',
+            barGap: '30%',
+            barWidth: '20',
+            xAxisIndex: 0,
+            yAxisIndex: 0,
+            itemStyle: {
+              normal: {
+                barBorderRadius: [30, 0, 0, 30],
+                borderWidth: 0
+              }
+            },
+            emphasis: {
+              itemStyle: {
+                barBorderWidth: 1,
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowOffsetY: 0,
+                shadowColor: 'rgba(0,0,0,0.5)'
+              }
+            },
+            data: [-102]
+          },
+          {
+            name: '加分',
+            type: 'bar',
+            stack: '总量',
+            barGap: '30%',
+            barWidth: '20',
+            xAxisIndex: 0,
+            yAxisIndex: 0,
+            itemStyle: {
+              normal: {
+                barBorderRadius: [0, 30, 30, 0],
+                borderWidth: 0
+              }
+            },
+            emphasis: {
+              itemStyle: {
+                barBorderWidth: 1,
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowOffsetY: 0,
+                shadowColor: 'rgba(0,255,0,0.5)'
+              }
+            },
+            data: [722]
+          },
+        ]
+      };
+      myChart.clear()
+      myChart.setOption(option)
+      window.addEventListener('resize', function () {
+        myChart.resize()
+      })
+
+    }
+  },
+  mounted() {
+    this.doRender()
+  },
+  //   watch: {
+  //     '$store.state.dashboard.artDashboard': {
+  //       deep: true,
+  //       immediate: true,
+  //       handler(n, o) {
+
+  //       }
+  //     }
+  //   }
+}
+</script>
+
+<style>
+.art-echart {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 100 - 0
TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseScorePie.vue

@@ -0,0 +1,100 @@
+<template>
+  <div id="moralScorePie" class="art-echart" style="height: 500px"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    }
+  },
+  methods: {
+    doRender() {
+      let myChart = this.$echarts.init(document.getElementById('moralScorePie'))
+      let option = {
+        toolbox: {
+          show: false,
+        },
+        title: {
+          text: '684',
+          top: '30%',
+          left: 'center',
+          textStyle: {
+            color: ' #0baefd',
+            fontSize: 26,
+            fontWeight: '600',
+          },
+          subtext: '德育总分',
+          subtextStyle: {
+            color: '#fff',
+            fontSize: 14,
+          },
+        },
+        grid: {
+          width: '100%',
+          height: '80%',
+          top: '0%',
+          containLabel: true
+        },
+        color: ['#1370fb', '#fd5151'],
+        tooltip: {
+          trigger: 'item',
+          formatter: '{b}: {d}%',
+          backgroundColor: 'rgba(47,37,198,0.75)',
+          borderColor: '#2880FF',
+          borderWidth: 1,
+          textStyle: {
+            color: '#fff'
+          }
+        },
+        series: [
+          {
+            name: 'Nightingale Chart',
+            type: 'pie',
+            radius: ['70%', '90%'],
+            center: ['50%', '45%'],
+            label: { show: false },
+            labelLine: { show: false },
+            selectedOffset: 30,
+            selectedMode: true,
+            itemStyle: {
+              borderRadius: 8
+            },
+            data: [
+              { value: 94, name: '加分' },
+              { value: 6, name: '减分' },
+            ]
+          }
+        ]
+      };
+      myChart.clear()
+      myChart.setOption(option)
+      window.addEventListener('resize', function () {
+        myChart.resize()
+      })
+
+    }
+  },
+  mounted() {
+    this.doRender()
+  },
+  //   watch: {
+  //     '$store.state.dashboard.artDashboard': {
+  //       deep: true,
+  //       immediate: true,
+  //       handler(n, o) {
+
+  //       }
+  //     }
+  //   }
+}
+</script>
+
+<style>
+.art-echart {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 146 - 0
TEAMModelOS/ClientApp/src/view/dashboard/moral/BaseSubLine.vue

@@ -0,0 +1,146 @@
+<template>
+  <div id="studySubjectLine" class="art-echart"></div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      option: null,
+    }
+  },
+  methods: {
+    doRender() {
+      let myChart = this.$echarts.init(document.getElementById('studySubjectLine'))
+      let name = "单科平均分"
+      let xData = [
+        "语文",
+        "数学",
+        "英语",
+        "音乐"
+      ]
+      let yData = [
+        68,
+        84,
+        77,
+        72
+      ]
+      let option = {
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {            // 坐标轴指示器,坐标轴触发有效
+            type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
+          },
+          backgroundColor: 'rgba(13,5,30,.6)',
+          borderColor: ' rgba(255,255,255,.2)',
+          borderWidth: 1,
+          padding: 5
+        },
+        legend: {
+          show: false
+        },
+        grid: {
+          left: '3%',
+          right: '8%',
+          bottom: '5%',
+          top: ' 15%',
+          containLabel: true
+        },
+        xAxis: [
+          {
+            type: 'category',
+            data: xData,
+            splitLine: {
+              show: false
+            },
+            axisLabel: {
+              show: true,
+              // interval: '0',//X轴坐标全显示
+              textStyle: {
+                color: "#fff"
+              }
+            }
+          }
+        ],
+        yAxis: [
+          {
+            type: 'value',
+            splitLine: {
+              show: false
+            },
+            axisLabel: {
+              show: true,
+              textStyle: {
+                color: "#fff"
+              }
+            }
+          }
+        ],
+        series: [
+          {
+            name: name,
+            type: 'bar',
+            barMaxWidth: 20,
+            barMinWidth: 10,
+            minWidth: 5,
+            xAxisIndex: 0,
+            yAxisIndex: 0,
+            itemStyle: {
+              barBorderRadius: 20,
+              normal: {
+                barBorderRadius: 10,
+                color: function (params) {
+                  var colors = []
+                  var maxIndex = 1;
+                  if (params.dataIndex == maxIndex) {
+                    colors = ["#fc532d", "#fe7018", "#ff8706"]
+                  } else {
+                    colors = ["#00aef2", "#0077fe", "#0072ff"];
+                  }
+                  return new echarts.graphic.LinearGradient(0, 0, 1, 0,
+                    [
+                      { offset: 0, color: colors[0] },
+                      { offset: 0.5, color: colors[1] },
+                      { offset: 1, color: colors[2] }
+                    ]);
+                }
+              },
+              emphasis: {
+                color: "#fc532d"
+              }
+            },
+            zlevel: 1,
+            data: yData
+          }
+        ]
+      };
+      myChart.clear()
+      myChart.setOption(option)
+      window.addEventListener('resize', function () {
+        myChart.resize()
+      })
+
+    }
+  },
+  mounted() {
+    this.doRender()
+  },
+  //   watch: {
+  //     '$store.state.dashboard.artDashboard': {
+  //       deep: true,
+  //       immediate: true,
+  //       handler(n, o) {
+
+  //       }
+  //     }
+  //   }
+}
+</script>
+
+<style>
+.art-echart {
+  width: 100%;
+  height: 100%;
+  margin: 0 auto;
+  display: block;
+}
+</style>

+ 115 - 0
TEAMModelOS/ClientApp/src/view/dashboard/moral/MoralDash.less

@@ -0,0 +1,115 @@
+.moral-dash-container {
+    // .right-box-top {
+    //     height: 64% !important;
+    // }
+
+    .right-box-middle {
+        height: 32% !important;
+    }
+
+    .top {
+        flex-direction: column !important;
+        height: 100% !important;
+
+        .dv-border-box-13 {
+            width: 100% !important;
+            height: 50% !important;
+        }
+    }
+
+    .rank-wrap {
+        display: flex;
+        flex-direction: column;
+        padding: 10px;
+        width: 100%;
+        overflow: auto;
+
+        .stu-rank-item {
+            width: 100%;
+            margin-bottom: 10px;
+            display: flex;
+
+            .border-box-content {
+                display: flex;
+                align-items: center;
+            }
+
+            .img-avatar {
+                border-radius: 100px;
+                margin: 0 20px
+            }
+
+            .img-crown {
+                width: 40px;
+                transform: rotate(30deg);
+            }
+
+            .rank-index {
+                display: inline-block;
+                font-weight: bold;
+                font-size: 16px;
+                background-color: rgba(0, 167, 245, 0.767);
+                width: 25px;
+                height: 25px;
+                text-align: center;
+                margin: 0 8px;
+                line-height: 25px;
+                border-radius: 40px;
+                color: #fff;
+            }
+
+            .rank-score {
+                margin-left: auto;
+                font-weight: bold;
+                font-size: 22px;
+                color: rgb(60, 146, 245);
+                display: flex;
+                flex-direction: column;
+                align-items: center
+            }
+
+            .stu-info {
+                height: 100%;
+                display: flex;
+                flex-direction: column;
+                justify-content: space-between;
+
+                .name {
+                    font-weight: bold;
+                    font-size: 16px;
+                }
+            }
+        }
+    }
+
+    .moral-honor-avatar {
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: center;
+        align-items: center;
+        width: 100%;
+        padding: 20px 0;
+
+        .honor-item {
+            position: relative;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+            margin: 5px 30px;
+
+            .img-avatar {
+                border-radius: 50%;
+                border: 3px solid #58a8bb;
+                cursor: pointer;
+            }
+
+            .img-crown {
+                position: absolute;
+                width: 40px;
+                top: -15px;
+                left: 0px;
+            }
+        }
+    }
+}

+ 238 - 0
TEAMModelOS/ClientApp/src/view/dashboard/moral/MoralDash.vue

@@ -0,0 +1,238 @@
+<template>
+  <div class="body-box moral-dash-container">
+    <!-- 左侧 -->
+    <div class="left-box">
+      <div class="left-box-top">
+        <dv-border-box-12>
+          <div class="dashboard-block">
+            <div class="block-content">
+              <div class="static-wrap">
+                <div class="item" v-for="(item,index) in staticArr">
+                  <span class="num" :style="{color:item.color}">
+                    <countTo :startVal='0' :endVal='item.val' :duration='1000' class="count-num"></countTo>
+                  </span>
+                  <span class="label">{{ item.label }}</span>
+                </div>
+              </div>
+              <!-- <BaseLine></BaseLine> -->
+            </div>
+          </div>
+        </dv-border-box-12>
+      </div>
+      <div class="left-box-bottom">
+        <div class="left-bottom-left">
+          <dv-border-box-13>
+            <div class="dashboard-block">
+              <div class="block-title">
+                <span>关键指标分布</span>
+                <dv-decoration-1 style="width:150px;height:20px;" />
+              </div>
+              <div class="block-content">
+                <BaseWordCloud></BaseWordCloud>
+              </div>
+            </div>
+          </dv-border-box-13>
+          <dv-border-box-13>
+            <div class="dashboard-block">
+              <div class="block-title">
+                <span>学生德育常规表现</span>
+                <dv-decoration-1 style="width:150px;height:20px;" />
+              </div>
+              <div class="block-content">
+                <BaseScoreBar></BaseScoreBar>
+              </div>
+            </div>
+          </dv-border-box-13>
+        </div>
+        <div class="left-bottom-right">
+          <div class="top">
+            <dv-border-box-13>
+              <div class="dashboard-block">
+                <div class="block-title">
+                  <span>德育风采展示</span>
+                  <dv-decoration-1 style="width:150px;height:20px;" />
+                </div>
+                <div class="block-content">
+                  <BaseCarousel></BaseCarousel>
+                </div>
+              </div>
+            </dv-border-box-13>
+            <dv-border-box-13>
+              <div class="dashboard-block">
+                <div class="block-title">
+                  <span>班级荣誉表现</span>
+                  <dv-decoration-1 style="width:150px;height:20px;" />
+                </div>
+                <div class="block-content">
+                  <dv-scroll-board :config="classRankConfig" />
+                </div>
+              </div>
+            </dv-border-box-13>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 右侧 -->
+    <div class="right-box">
+      <div class="right-box-top">
+        <dv-border-box-13>
+          <div class="dashboard-block">
+            <div class="block-title">
+              <span>德育加减分</span>
+              <dv-decoration-1 style="width:150px;height:20px;" />
+            </div>
+            <div class="block-content" style="display:flex;flex-direction:column;align-items: center">
+              <BaseScorePie></BaseScorePie>
+              <p style="text-align:center;font-weight:bold;margin-top:-5px;margin-bottom:5px">
+                <span> - 102 扣分</span>
+                <span style="display:inline-block;margin: 0 10px"></span>
+                <span> 加分 + 722</span>
+              </p>
+              <BaseScoreLine></BaseScoreLine>
+              <br>
+            </div>
+          </div>
+        </dv-border-box-13>
+      </div>
+      <div class="right-box-middle">
+        <dv-border-box-13>
+          <div class="dashboard-block">
+            <div class="block-title">
+              <span>问题预警</span>
+              <dv-decoration-1 style="width:150px;height:20px;" />
+            </div>
+            <div class="block-content">
+              <dv-scroll-ranking-board :config="warningRank" style="width:90%;margin-left:5%" />
+            </div>
+          </div>
+        </dv-border-box-13>
+      </div>
+      <div class="right-box-bottom">
+        <dv-border-box-13>
+          <div class="dashboard-block">
+            <div class="block-title">
+              <span>德育表现TOP5</span>
+              <dv-decoration-1 style="width:150px;height:20px;" />
+            </div>
+            <div class="block-content">
+              <div class="moral-honor-avatar">
+                <div class="honor-item" v-for="(item,index) in stuTopArr" :key="index">
+                  <img class="img-avatar" @click="goStudent()" src="https://paas-admin.xydqq.cn/img/avatar.647bbbfe.png" alt="" width="60">
+                  <img class="img-crown" src="@/assets/dashboard/student/icon_crown.png" alt="" v-show="index === 0">
+                  <img class="img-crown" src="@/assets/dashboard/student/icon_crown2.png" alt="" v-show="index === 1">
+                  <img class="img-crown" src="@/assets/dashboard/student/icon_crown3.png" alt="" v-show="index === 2">
+                  <span style="margin-top:5px">学生姓名</span>
+                </div>
+              </div>
+            </div>
+          </div>
+        </dv-border-box-13>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import countTo from 'vue-count-to'
+import BaseCircle from '@/components/dashboard/student/BaseCircle'
+import BaseScoreBar from './BaseScoreBar'
+import BaseScorePie from './BaseScorePie'
+import BaseScoreLine from './BaseScoreLine'
+import BaseCarousel from './BaseCarousel'
+import BaseExamLine from './BaseExamLine'
+import BaseSubLine from './BaseSubLine'
+import BaseStudyRadar from './BaseRadar'
+import BaseWordCloud from '@/components/dashboard/studentAll/BaseWordCloud'
+export default {
+  components: {
+    countTo,
+    BaseCircle,
+    BaseCarousel,
+    BaseExamLine,
+    BaseScorePie,
+    BaseScoreLine,
+    BaseScoreBar,
+    BaseSubLine,
+    BaseStudyRadar,
+    BaseWordCloud
+  },
+  data() {
+    return {
+      staticArr: [
+        {
+          label: '学生总数',
+          color: '#7ec4ff',
+          val: 7944
+        },
+        {
+          label: '教师参与数',
+          color: '#7ec4ff',
+          val: 135
+        }, {
+          label: '家长参与数',
+          color: '#ff8e2e',
+          val: 44
+        },
+        {
+          label: '德育活动总数',
+          color: '#20d99d',
+          val: 12
+        }
+      ],
+      stuTopArr: new Array(5),
+      classRankConfig: {
+        header: ['<span style="color:#32c5e9;font-weight: bold;">班级</span>', '<span style="color:#32c5e9;font-weight: bold;">德育总分</span>', '<span style="color:#32c5e9;font-weight: bold;">流动红旗(次)</span>', '<span style="color:#32c5e9;font-weight: bold;">星级班级(次)</span>'],
+        data: [
+          ['五年级1班', '84.3 分', '8', '5'],
+          ['五年级2班', '82.6 分', '10', '5'],
+          ['五年级3班', '76.0 分', '6', '3'],
+          ['五年级4班', '74.1 分', '4', '1'],
+          ['五年级5班', '64.3 分', '2', '0'],
+          ['五年级6班', '54.3 分', '2', '0'],
+        ],
+        align: ['center', 'center', 'center', 'center', 'center'],
+        rowNum: 6,
+        index: true,
+        headerHeight: 30,
+        headerBGC: "transparent", //表头
+        oddRowBGC: "transparent", //奇数行
+        evenRowBGC: "transparent", //偶数行
+      },
+      warningRank: {
+        data: [
+          {
+            name: '破坏公物',
+            value: 55
+          },
+          {
+            name: '不讲卫生',
+            value: 96
+          },
+          {
+            name: '大声喧哗',
+            value: 78
+          },
+          {
+            name: '乱丢垃圾',
+            value: 66
+          },
+          {
+            name: '欺负同学',
+            value: 6
+          }
+        ],
+        unit: ' 次'
+      },
+    }
+  }, methods: {
+    goStudent() {
+      this.$router.push('/stuDetails')
+    },
+  }
+}
+</script>
+
+<style lang="less">
+@import "MoralDash.less";
+// @import "../fiveEdu/FiveEdu.less";
+</style>

+ 23 - 18
TEAMModelOS/ClientApp/src/view/dashboard/study/StudyDash.vue

@@ -74,7 +74,7 @@
                         </span>
                         <img class="img-avatar" @click="goStudent()" src="https://paas-admin.xydqq.cn/img/avatar.647bbbfe.png" alt="" width="50">
                         <div class="stu-info">
-                          <p class="name">张三</p>
+                          <p class="name">学生姓名</p>
                           <p class="id">140015511001</p>
                         </div>
                         <span class="rank-score">
@@ -178,18 +178,18 @@ export default {
       classRankConfig: {
         header: ['<span style="color:#32c5e9;font-weight: bold;">班级</span>', '<span style="color:#32c5e9;font-weight: bold;">最高分</span>', '<span style="color:#32c5e9;font-weight: bold;">最低分</span>', '<span style="color:#32c5e9;font-weight: bold;">综合平均分</span>'],
         data: [
-          ['年级1班', '84.3 分', '84.3 分', '84.3 分'],
-          ['年级2班', '82.6 分', '84.3 分', '84.3 分'],
-          ['年级3班', '76.0 分', '84.3 分', '84.3 分'],
-          ['年级4班', '74.1 分', '84.3 分', '84.3 分'],
-          ['年级5班', '65.8 分', '84.3 分', '84.3 分'],
-          ['年级6班', '64.3 分', '84.3 分', '84.3 分'],
-          ['年级1班', '84.3 分', '84.3 分', '84.3 分'],
-          ['年级2班', '82.6 分', '84.3 分', '84.3 分'],
-          ['年级3班', '76.0 分', '84.3 分', '84.3 分'],
-          ['年级4班', '74.1 分', '84.3 分', '84.3 分'],
-          ['年级5班', '65.8 分', '84.3 分', '84.3 分'],
-          ['年级6班', '64.3 分', '84.3 分', '84.3 分'],
+          ['年级1班', '84.3 分', '84.3 分', '84.3 分'],
+          ['年级2班', '82.6 分', '84.3 分', '84.3 分'],
+          ['年级3班', '76.0 分', '84.3 分', '84.3 分'],
+          ['年级4班', '74.1 分', '84.3 分', '84.3 分'],
+          ['年级5班', '65.8 分', '84.3 分', '84.3 分'],
+          ['年级6班', '64.3 分', '84.3 分', '84.3 分'],
+          ['年级1班', '84.3 分', '84.3 分', '84.3 分'],
+          ['年级2班', '82.6 分', '84.3 分', '84.3 分'],
+          ['年级3班', '76.0 分', '84.3 分', '84.3 分'],
+          ['年级4班', '74.1 分', '84.3 分', '84.3 分'],
+          ['年级5班', '65.8 分', '84.3 分', '84.3 分'],
+          ['年级6班', '64.3 分', '84.3 分', '84.3 分'],
         ],
         align: ['center'],
         rowNum: 12,
@@ -201,29 +201,34 @@ export default {
       stuRankConfig: {
         data: [
           {
-            name: '詹姆斯',
+            name: '学生1',
             value: 55
           },
           {
-            name: '库里',
+            name: '学生2',
             value: 96
           },
           {
-            name: '奥尼尔',
+            name: '学生3',
             value: 78
           },
           {
-            name: '韦德',
+            name: '学生4',
             value: 66
           },
           {
-            name: '科比',
+            name: '学生5',
             value: 80
           }
         ],
         unit: '分'
       },
     }
+  },
+  methods: {
+    goStudent() {
+      this.$router.push('/stuDetails')
+    },
   }
 }
 </script>

+ 10 - 2
TEAMModelOS/Controllers/School/ArtReviewController.cs

@@ -159,9 +159,17 @@ namespace TEAMModelOS.Controllers
                     comment_subject_painting = $"{_subject_painting}";
                 }
             }
-
+            List<string> studentIds = new List<string>();
+            if (request.TryGetProperty("studentIds", out JsonElement _studentIds) && _studentIds.ValueKind.Equals(JsonValueKind.Array))
+            {
+                studentIds = _studentIds.ToObject<List<string>>();
+            }
             var client = _azureCosmos.GetCosmosClient();
+
             string query = $" select value c from c where c.school  = '{_schoolId}' ";
+            if (studentIds.Any()) {
+                query = $" select value c from c where c.school  = '{_schoolId}' and c.studentId in ({string.Join(",", studentIds.Select(z => $"'{z}'"))})";
+            }
             List<StudentArtResult> artResults = new List<StudentArtResult>();
             ArtEvaluation art = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ArtEvaluation>($"{_artId}", new PartitionKey($"Art-{_schoolId}"));
             ArtSetting artSetting = await client.GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemAsync<ArtSetting>($"{_areaId}", new PartitionKey($"ArtSetting"));
@@ -475,7 +483,7 @@ namespace TEAMModelOS.Controllers
                 studentPdfs.Add(studentPdf);
             });
             _ = _httpTrigger.RequestHttpTrigger(new { studentPdfs = studentPdfs, schoolCode = $"{_schoolId}" }, _option.Location, "gen-art-pdf");
-            return Ok(new { studentPdfs = studentPdfs });
+            return Ok(new { count = studentPdfs.Count(), studentIds=studentPdfs.Select(z=>z.studentId)});
         }
 
         private List<ArtPointPdf> GetBlockAndDimension(double score,double tscore ,string subjectId , string point, List<KeyValuePair<string, List<Block>>> subjectBindBlocks, ArtSetting artSetting) {

+ 21 - 0
TEAMModelOS/Controllers/XTest/TestController.cs

@@ -70,6 +70,27 @@ namespace TEAMModelOS.Controllers
             _coreAPIHttpService = coreAPIHttpService;
             _searcher = searcher;
         }
+        [ProducesDefaultResponseType]
+        [HttpPost("get-studentId")]
+        public async Task<IActionResult> GetStudentId(JsonElement json) {
+            List<string> ids = new List<string>();
+
+            await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Student")
+                .GetItemQueryStreamIterator(queryText: "  SELECT distinct value c.studentId  FROM c where c.pk='OverallEducation' and c.schoolCode='ydzt'  ", requestOptions :new QueryRequestOptions { }))
+            {
+                using var djson = await JsonDocument.ParseAsync(item.ContentStream);
+                if (djson.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                {
+                    foreach (var obj in djson.RootElement.GetProperty("Documents").EnumerateArray())
+                    {
+                        ids.Add(obj.ToObject<string>());
+                    }
+                }
+            }
+            return Ok(ids);
+        }
+
+
         [ProducesDefaultResponseType]
         [HttpPost("get-semester")]
         public async Task<IActionResult> GetSemester(JsonElement json) {

+ 5 - 4
TEAMModelOS/appsettings.json

@@ -26,16 +26,17 @@
     "Cosmos": {
       "ConnectionString": "AccountEndpoint=https://teammodelos.documents.azure.cn:443/;AccountKey=clF73GwPECfP1lKZTCvs8gLMMyCZig1HODFbhDUsarsAURO7TcOjVz6ZFfPqr1HzYrfjCXpMuVD5TlEG5bFGGg==;"
     },
-    "CosmosDep": {
-      "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;"
-    },
     "Redis": {
       "ConnectionString": "CoreRedisCN.redis.cache.chinacloudapi.cn:6380,password=LyJWP1ORJdv+poXWofAF97lhCEQPg1wXWqvtzXGXQuE=,ssl=True,abortConnect=False"
     },
     "ServiceBus": {
       "ConnectionString": "Endpoint=sb://coreiotservicebuscnpro.servicebus.chinacloudapi.cn/;SharedAccessKeyName=TEAMModelOS;SharedAccessKey=llRPBMDJG9w1Nnifj+pGhV0g4H2REcq0PjvX2qqpcOg=",
       "ActiveTask": "active-task",
-      "NoticeTask": "notice-task"
+      "ItemCondQueue": "itemcond",
+      "GenPdfQueue": "genpdf"
+    },
+    "SignalR": {
+      "ConnectionString": "Endpoint=https://channel.signalr.azure.cn;AccessKey=AtcB7JYFNUbUXb1rGxa3PVksQ2X5YSv3JOHZR9J88tw=;Version=1.0;"
     }
   },
   "HaBookAuth": {