浏览代码

Merge branch 'develop' of http://52.130.252.100:10000/TEAMMODEL/TEAMModelOS into develop

CrazyIter_Bin 1 年之前
父节点
当前提交
d92125eb98

文件差异内容过多而无法显示
+ 3 - 1
TEAMModelBI/Controllers/BITmid/TmidController.cs


+ 41 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/IotTeachingData.cs

@@ -141,6 +141,38 @@ namespace TEAMModelOS.SDK.Models.Cosmos.Common
         /// T課堂 0:false 1:true
         /// T課堂 0:false 1:true
         /// </summary>
         /// </summary>
         public string tlesson { get; set; }
         public string tlesson { get; set; }
+        /// <summary>
+        /// 課堂中課堂中使用記分板 0:false 1:true
+        /// </summary>
+        public string useScoreBoard { get; set; }
+        /// <summary>
+        /// 學習參與度指數
+        /// </summary>
+        public int learnParticipation { get; set; }
+        /// <summary>
+        /// 是否計算學習參與度 (學習參與度指數>0:true ==0:false)
+        /// </summary>
+        public string learnParticipationCnt { get; set; }
+        /// <summary>
+        /// 協作任務數
+        /// </summary>
+        public int coopMission { get; set; }
+        /// <summary>
+        /// 協作作品數
+        /// </summary>
+        public int coopWork { get; set; }
+        /// <summary>
+        /// 協作總貢獻度
+        /// </summary>
+        public int coopContributionT { get; set; }
+        /// <summary>
+        /// 互評活動次數
+        /// </summary>
+        public int peerAct { get; set; }
+        /// <summary>
+        /// 互評學生參與總次數
+        /// </summary>
+        public int peerStuParticipationT { get; set; }
     }
     }
 
 
     /// <summary>
     /// <summary>
@@ -194,5 +226,14 @@ namespace TEAMModelOS.SDK.Models.Cosmos.Common
         public int useIes5Test { get; set; } //課堂中有使用IES5測驗模式
         public int useIes5Test { get; set; } //課堂中有使用IES5測驗模式
         public int usePaperTest { get; set; } //課堂中有使用紙本測驗模式
         public int usePaperTest { get; set; } //課堂中有使用紙本測驗模式
         public int useExcelTest { get; set; } //課堂中有使用Excel測驗模式
         public int useExcelTest { get; set; } //課堂中有使用Excel測驗模式
+        public int useScoreBoard { get; set; } //課堂中使用記分板
+        public int learnParticipationCnt { get; set; } //學習參與度次數
+        public long learnParticipationT { get; set; } //學習參與度指數(總和)
+        public decimal learnParticipation { get; set; } //學習參與度指數(平均)
+        public int coopMission { get; set; } //協作任務數
+        public int coopWork { get; set; } //協作作品數
+        public long coopContributionT { get; set; } //協作總貢獻度
+        public int peerAct { get; set; } //互評活動次數
+        public long peerStuParticipationT { get; set; } //互評學生參與總次數
     }
     }
 }
 }

文件差异内容过多而无法显示
+ 35 - 2
TEAMModelOS.SDK/Models/Service/BI/BIProdAnalysis.cs


+ 1 - 1
TEAMModelOS/ClientApp/package.json

@@ -83,7 +83,7 @@
     "vuex": "^3.0.1",
     "vuex": "^3.0.1",
     "vuex-oidc": "^3.3.0",
     "vuex-oidc": "^3.3.0",
     "vuex-router-sync": "^5.0.0",
     "vuex-router-sync": "^5.0.0",
-    "wangeditor": "4.4.1",
+    "wangeditor": "^4.4.1",
     "webpack": "^4.46.0",
     "webpack": "^4.46.0",
     "xlsx": "^0.17.1"
     "xlsx": "^0.17.1"
   },
   },

+ 4 - 2
TEAMModelOS/ClientApp/src/components/public/frontEndMain/Index.vue

@@ -90,8 +90,8 @@
 <template>
 <template>
     <div id="login" :class="[isShowZY ? 'login zylogin':'login']" :style="{backgroundImage:bgImg}">
     <div id="login" :class="[isShowZY ? 'login zylogin':'login']" :style="{backgroundImage:bgImg}">
         <div class="login-mark" v-show="isShowTMD">
         <div class="login-mark" v-show="isShowTMD">
-            <img height="42" src="@/assets/login/ies5_logo_2.svg">
-            <span class="login-title">
+            <img height="30" src="@/assets/login/ies5_logo_2.svg">
+            <span class="login-title" v-if="!queryCode">
                 {{$t('system.title')}}
                 {{$t('system.title')}}
             </span>
             </span>
         </div>
         </div>
@@ -136,6 +136,7 @@ export default {
             version: '',
             version: '',
             isShowTMD: false,
             isShowTMD: false,
             isShowZY: false,
             isShowZY: false,
+            queryCode:''
         }
         }
     },
     },
     computed: {
     computed: {
@@ -164,6 +165,7 @@ export default {
     created() {
     created() {
         let queryData = this.$route.query
         let queryData = this.$route.query
         console.log(this.$route)
         console.log(this.$route)
+        this.queryCode = queryData.code
         // 統一處理預設登入學校
         // 統一處理預設登入學校
         this.setLoginSchoolCode()
         this.setLoginSchoolCode()
         this.$api.login.getSystemInfo({}).then(
         this.$api.login.getSystemInfo({}).then(

+ 2 - 2
TEAMModelOS/ClientApp/src/view/art/AreaArt.vue

@@ -613,10 +613,10 @@
 				this.$api.elegant
 				this.$api.elegant
 					.findElegantStatistics({
 					.findElegantStatistics({
 						scope: "area",
 						scope: "area",
-						code: sessionStorage.getItem("areaId")
+						code: sessionStorage.getItem("areaId"),
+						periodType: this.periodId
 					})
 					})
 					.then((res) => {
 					.then((res) => {
-						console.log(res);
 						this.artBarData = res.schoolDatas.map((school) => {
 						this.artBarData = res.schoolDatas.map((school) => {
 							return {
 							return {
 								name: school.name,
 								name: school.name,

+ 76 - 71
TEAMModelOS/ClientApp/src/view/elegant/BaseElegantDash.vue

@@ -1,6 +1,6 @@
 <template>
 <template>
 	<div class="elegant-dash-container">
 	<div class="elegant-dash-container">
-        <Spin fix v-if="isLoading"></Spin>
+		<Spin fix v-if="isLoading"></Spin>
 		<!-- <div class="title">
 		<!-- <div class="title">
 			<span>数据总览</span>
 			<span>数据总览</span>
 			<span class="btn-details" @click="goDetails">数据详情 ></span>
 			<span class="btn-details" @click="goDetails">数据详情 ></span>
@@ -9,32 +9,32 @@
 			<div class="count-item">
 			<div class="count-item">
 				<p class="label">全部活动数</p>
 				<p class="label">全部活动数</p>
 				<p class="value">{{ countArr[0] }}</p>
 				<p class="value">{{ countArr[0] }}</p>
-                <img src="../../assets/source/folder.png">
+				<img src="../../assets/source/folder.png" />
 			</div>
 			</div>
 			<div class="count-item">
 			<div class="count-item">
 				<p class="label">德育风采数</p>
 				<p class="label">德育风采数</p>
 				<p class="value">{{ countArr[1] }}</p>
 				<p class="value">{{ countArr[1] }}</p>
-                <img src="../../assets/mark/5.png" style="width: 70px">
+				<img src="../../assets/mark/5.png" style="width: 70px" />
 			</div>
 			</div>
 			<div class="count-item">
 			<div class="count-item">
 				<p class="label">艺术特色数</p>
 				<p class="label">艺术特色数</p>
 				<p class="value">{{ countArr[2] }}</p>
 				<p class="value">{{ countArr[2] }}</p>
-                <img src="../../assets/mark/7.png" style="width: 70px">
+				<img src="../../assets/mark/7.png" style="width: 70px" />
 			</div>
 			</div>
 			<div class="count-item">
 			<div class="count-item">
 				<p class="label">图片总数</p>
 				<p class="label">图片总数</p>
 				<p class="value">{{ countArr[3] }}</p>
 				<p class="value">{{ countArr[3] }}</p>
-                <img src="../../assets/source/image.png">
+				<img src="../../assets/source/image.png" />
 			</div>
 			</div>
 			<div class="count-item">
 			<div class="count-item">
 				<p class="label">视频总数</p>
 				<p class="label">视频总数</p>
 				<p class="value">{{ countArr[4] }}</p>
 				<p class="value">{{ countArr[4] }}</p>
-                <img src="../../assets/source/video.png">
+				<img src="../../assets/source/video.png" />
 			</div>
 			</div>
 			<div class="count-item">
 			<div class="count-item">
 				<p class="label">文档总数</p>
 				<p class="label">文档总数</p>
 				<p class="value">{{ countArr[5] }}</p>
 				<p class="value">{{ countArr[5] }}</p>
-                <img src="../../assets/source/pdf.png">
+				<img src="../../assets/source/pdf.png" />
 			</div>
 			</div>
 		</div>
 		</div>
 		<div class="chart-wrap">
 		<div class="chart-wrap">
@@ -46,12 +46,12 @@
 					<BasePie echartsId="pie1" :echartData="artCount"></BasePie>
 					<BasePie echartsId="pie1" :echartData="artCount"></BasePie>
 				</div>
 				</div>
 			</div>
 			</div>
-            <div class="chart-block" style="margin: 0 1%;width: 26%">
+			<div class="chart-block" style="margin: 0 1%; width: 26%">
 				<div class="chart-title">
 				<div class="chart-title">
 					<p class="title">艺术特色素材文字云</p>
 					<p class="title">艺术特色素材文字云</p>
 				</div>
 				</div>
 				<div class="chart-content">
 				<div class="chart-content">
-                    <BaseElegantCloud echartsId="cloud1" :echartData="keyCounts"></BaseElegantCloud>
+					<BaseElegantCloud echartsId="cloud1" :echartData="keyCounts"></BaseElegantCloud>
 				</div>
 				</div>
 			</div>
 			</div>
 			<div class="chart-block chart-right">
 			<div class="chart-block chart-right">
@@ -64,7 +64,7 @@
 			</div>
 			</div>
 		</div>
 		</div>
 		<div class="chart-wrap">
 		<div class="chart-wrap">
-			<div class="chart-block" style="width: 26%;">
+			<div class="chart-block" style="width: 26%">
 				<div class="chart-title">
 				<div class="chart-title">
 					<p class="title">德育风采素材类型</p>
 					<p class="title">德育风采素材类型</p>
 				</div>
 				</div>
@@ -72,7 +72,7 @@
 					<BasePie echartsId="pie2" :echartData="elegantCount"></BasePie>
 					<BasePie echartsId="pie2" :echartData="elegantCount"></BasePie>
 				</div>
 				</div>
 			</div>
 			</div>
-			<div class="chart-block"  style="margin: 0 1%;width: 26%">
+			<div class="chart-block" style="margin: 0 1%; width: 26%">
 				<div class="chart-title">
 				<div class="chart-title">
 					<p class="title">德育风采素材文字云</p>
 					<p class="title">德育风采素材文字云</p>
 				</div>
 				</div>
@@ -126,63 +126,68 @@
 	import BaseUploadLine from "./BaseUploadLine.vue";
 	import BaseUploadLine from "./BaseUploadLine.vue";
 	import BaseElegantCloud from "./BaseElegantCloud.vue";
 	import BaseElegantCloud from "./BaseElegantCloud.vue";
 	export default {
 	export default {
-		props:['schoolCode'],
+		props: ["schoolCode"],
 		components: {
 		components: {
 			BasePie,
 			BasePie,
 			BaseBar,
 			BaseBar,
 			BaseUploadLine,
 			BaseUploadLine,
-            BaseElegantCloud
+			BaseElegantCloud
+		},
+		data() {
+			return {
+				isLoading: false,
+				elegantCount: [],
+				artCount: [],
+				keyCounts: [],
+				countArr: [0, 0, 0, 0, 0, 0]
+			};
+		},
+		created() {
+			this.initDash();
 		},
 		},
-        data(){
-            return {
-                isLoading:false,
-                elegantCount:[],
-                artCount:[],
-                keyCounts:[],
-                countArr:[0,0,0,0,0,0]
-            }
-        },
-        created(){
-            this.isLoading = true
-            this.$api.elegant.findElegantStatistics({
-                "scope": "school",
-                "code": this.schoolCode || localStorage.getItem("login_schoolCode")
-            })
-            .then((res) => {
-                console.log(res);
-                this.isLoading = false
-                let artItems = ['艺术特色','课程活动','艺术社团','艺术活动',"理想信念","社会责任","行为习惯","演奏", "影视", "舞蹈", "戏剧", "常规活动", "获奖活动"]
-                let elegantItems = ['德育风采',"理想信念","社会责任","行为习惯","读书分享","思想沙龙","文学创作","社会服务","文化交流","思德教育","反思日志","小组合作","行为习惯挑战"]
-                let elegantCount = elegantItems.map(item => {
-                    return {
-                        name:item,
-                        count: res.items.find(i => i.id === item) ? res.items.find(i => i.id === item).count : 0
-                    }
-                })
-                let artCount = artItems.map(item => {
-                    return {
-                        name:item,
-                        count: res.items.find(i => i.id === item) ? res.items.find(i => i.id === item).count : 0
-                    }
-                })
-                this.keyCounts = res.itemKeys
-                this.elegantCount = elegantCount
-                this.artCount = artCount
-                console.error(artCount)
-                this.countArr = [
-                    elegantCount[0].count + artCount[0].count,
-                    elegantCount[0].count,
-                    artCount[0].count,
-                    res.imageCount,
-                    res.videoCount,
-                    res.docCount
-                ]
-            });
-        },
 		methods: {
 		methods: {
+			initDash() {
+				this.isLoading = true;
+				this.$api.elegant
+					.findElegantStatistics({
+						scope: "school",
+						code: this.schoolCode || localStorage.getItem("login_schoolCode"),
+						periodId: this.$store.state.user.curPeriod.id
+					})
+					.then((res) => {
+						console.log(res);
+						this.isLoading = false;
+						let artItems = ["艺术特色", "课程活动", "艺术社团", "艺术活动", "理想信念", "社会责任", "行为习惯", "演奏", "影视", "舞蹈", "戏剧", "常规活动", "获奖活动"];
+						let elegantItems = ["德育风采", "理想信念", "社会责任", "行为习惯", "读书分享", "思想沙龙", "文学创作", "社会服务", "文化交流", "思德教育", "反思日志", "小组合作", "行为习惯挑战"];
+						let elegantCount = elegantItems.map((item) => {
+							return {
+								name: item,
+								count: res.items.find((i) => i.id === item) ? res.items.find((i) => i.id === item).count : 0
+							};
+						});
+						let artCount = artItems.map((item) => {
+							return {
+								name: item,
+								count: res.items.find((i) => i.id === item) ? res.items.find((i) => i.id === item).count : 0
+							};
+						});
+						this.keyCounts = res.itemKeys;
+						this.elegantCount = elegantCount;
+						this.artCount = artCount;
+						this.countArr = [elegantCount[0].count + artCount[0].count, elegantCount[0].count, artCount[0].count, res.imageCount, res.videoCount, res.docCount];
+					});
+			},
 			goDetails() {
 			goDetails() {
 				this.$emit("goDetails");
 				this.$emit("goDetails");
 			}
 			}
+		},
+		watch: {
+			"$store.state.user.curSemester": {
+				deep: true,
+				handler(n, old) {
+					this.initDash();
+				}
+			}
 		}
 		}
 	};
 	};
 </script>
 </script>
@@ -220,7 +225,7 @@
 				flex-direction: column;
 				flex-direction: column;
 				justify-content: space-between;
 				justify-content: space-between;
 				padding: 20px;
 				padding: 20px;
-                position: relative;
+				position: relative;
 				.label {
 				.label {
 					font-size: 14px;
 					font-size: 14px;
 					color: #818181;
 					color: #818181;
@@ -232,13 +237,13 @@
 					color: #0d78be;
 					color: #0d78be;
 					letter-spacing: 1px;
 					letter-spacing: 1px;
 				}
 				}
-                img{
-                    width: 60px;
-                    position: absolute;
-                    bottom: 20px;
-                    right: 20px;
-                    opacity: .3;
-                }
+				img {
+					width: 60px;
+					position: absolute;
+					bottom: 20px;
+					right: 20px;
+					opacity: 0.3;
+				}
 			}
 			}
 		}
 		}
 		.chart-wrap {
 		.chart-wrap {
@@ -258,14 +263,14 @@
 
 
 				.title {
 				.title {
 					font-size: 14px;
 					font-size: 14px;
-                    display: flex;
-                    align-items: center;
+					display: flex;
+					align-items: center;
 					&::before {
 					&::before {
 						content: "";
 						content: "";
 						display: inline-block;
 						display: inline-block;
 						border: 3px solid #0d78be;
 						border: 3px solid #0d78be;
 						border-radius: 4px;
 						border-radius: 4px;
-                        height: 14px;
+						height: 14px;
 						margin-right: 10px;
 						margin-right: 10px;
 					}
 					}
 				}
 				}
@@ -277,7 +282,7 @@
 			}
 			}
 
 
 			.chart-right {
 			.chart-right {
-                flex:1;
+				flex: 1;
 				// width: 71%;
 				// width: 71%;
 				// margin-left: 1%;
 				// margin-left: 1%;
 			}
 			}

+ 24 - 11
TEAMModelOS/ClientApp/src/view/elegant/Elegant.vue

@@ -4,8 +4,8 @@
 		<div class="elegant-details-box">
 		<div class="elegant-details-box">
 			<div class="container-title">
 			<div class="container-title">
 				<div style="display: flex; align-items: center">
 				<div style="display: flex; align-items: center">
-					<span>{{isShowDash ? '数据总览' : '数据详情'}}</span>
-					<span class="btn-details" @click="isShowDash = !isShowDash">{{!isShowDash ? '数据总览' : '数据详情'}} ></span>
+					<span>{{ isShowDash ? "数据总览" : "数据详情" }}</span>
+					<span class="btn-details" @click="isShowDash = !isShowDash">{{ !isShowDash ? "数据总览" : "数据详情" }} ></span>
 				</div>
 				</div>
 				<div class="tools">
 				<div class="tools">
 					<Button shape="circle" @click="onAddElegant" icon="md-add">添加素材</Button>
 					<Button shape="circle" @click="onAddElegant" icon="md-add">添加素材</Button>
@@ -175,7 +175,7 @@
 				isLoading: false,
 				isLoading: false,
 				allList: [],
 				allList: [],
 				typeList: [],
 				typeList: [],
-				filterVal: ['0'],
+				filterVal: ["0"],
 				props: {
 				props: {
 					multiple: false,
 					multiple: false,
 					value: "id",
 					value: "id",
@@ -317,22 +317,23 @@
 			};
 			};
 		},
 		},
 		created() {
 		created() {
-			this.typeList = this._.cloneDeep(this.bizTypeData)
+			this.typeList = this._.cloneDeep(this.bizTypeData);
 			this.typeList.unshift({
 			this.typeList.unshift({
 				value: "0",
 				value: "0",
 				label: "全部素材",
 				label: "全部素材",
-				children:[]
-			})
+				children: []
+			});
 			this.schoolProfile = JSON.parse(decodeURIComponent(localStorage.school_profile || "{}", "utf-8"));
 			this.schoolProfile = JSON.parse(decodeURIComponent(localStorage.school_profile || "{}", "utf-8"));
 			this.$api.elegant
 			this.$api.elegant
 				.findElegants({
 				.findElegants({
 					admin: "1", //表示管理列表,其他则只获取有效的publish
 					admin: "1", //表示管理列表,其他则只获取有效的publish
+					periodId: this.$store.state.user.curPeriod.id,
 					stime: null, //可选
 					stime: null, //可选
 					etime: null //可选
 					etime: null //可选
 				})
 				})
 				.then((res) => {
 				.then((res) => {
 					this.originList = res.elegants.reverse();
 					this.originList = res.elegants.reverse();
-					this.onFilterTypeChange(['0']);
+					this.onFilterTypeChange(["0"]);
 					this.getTargetList();
 					this.getTargetList();
 				});
 				});
 		},
 		},
@@ -362,9 +363,9 @@
 				excel.export_array_to_excel(params);
 				excel.export_array_to_excel(params);
 				this.isLoading = false;
 				this.isLoading = false;
 			},
 			},
-			onFilterTypeChange(val,origin) {
-				let lastLabel = origin ? origin[origin.length - 1].label : ''
-				this.elegantList = val.includes('0') ? this._.cloneDeep(this.originList) : this.originList.filter((i) => i.bizType && i.bizType.includes(lastLabel));
+			onFilterTypeChange(val, origin) {
+				let lastLabel = origin ? origin[origin.length - 1].label : "";
+				this.elegantList = val.includes("0") ? this._.cloneDeep(this.originList) : this.originList.filter((i) => i.bizType && i.bizType.includes(lastLabel));
 			},
 			},
 			onPreview(file) {
 			onPreview(file) {
 				let fullLink = this.getFullPath(file.url);
 				let fullLink = this.getFullPath(file.url);
@@ -578,6 +579,7 @@
 					params.type = "school";
 					params.type = "school";
 					params.startTime = 111;
 					params.startTime = 111;
 					params.endTime = 222;
 					params.endTime = 222;
+					params.periodId = this.curPeriod.id;
 					this.$api.elegant.upsertElegants(params).then((res) => {
 					this.$api.elegant.upsertElegants(params).then((res) => {
 						if (!res.error) {
 						if (!res.error) {
 							this.btnLoading = false;
 							this.btnLoading = false;
@@ -692,7 +694,18 @@
 			"$store.state.user.curSemester": {
 			"$store.state.user.curSemester": {
 				deep: true,
 				deep: true,
 				handler(n, old) {
 				handler(n, old) {
-					this.getTargetList();
+					this.$api.elegant
+						.findElegants({
+							admin: "1", //表示管理列表,其他则只获取有效的publish
+							periodId: this.$store.state.user.curPeriod.id,
+							stime: null, //可选
+							etime: null //可选
+						})
+						.then((res) => {
+							this.originList = res.elegants.reverse();
+							this.onFilterTypeChange(["0"]);
+							this.getTargetList();
+						});
 				}
 				}
 			}
 			}
 		}
 		}

+ 1 - 1
TEAMModelOS/ClientApp/src/view/iot/areaiot.vue

@@ -381,7 +381,7 @@ export default {
      getAreaiots() {
      getAreaiots() {
        let schoolcodeArr = []
        let schoolcodeArr = []
        this.schoolList.forEach((item) => {schoolcodeArr.push(item.id)})
        this.schoolList.forEach((item) => {schoolcodeArr.push(item.id)})
-       let data = { schoolIds: schoolcodeArr }
+       let data = { areaId: sessionStorage.getItem('areaId'), schoolIds: schoolcodeArr }
        this.$api.iot.getAreaiot(data).then((res) => {
        this.$api.iot.getAreaiot(data).then((res) => {
         console.log(res,'area iot back')
         console.log(res,'area iot back')
           //header基础数据
           //header基础数据

+ 19 - 2
TEAMModelOS/ClientApp/src/view/login/page/Student.less

@@ -21,6 +21,23 @@
             
             
         }
         }
     }
     }
+
+    .query-school-info{
+        position: absolute;
+        top: 40px;
+        left: auto;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 50px;
+        color: #fff;
+        padding-bottom: 20px;
+        margin-bottom: 10px;
+
+        img {
+            margin-right: 15px;
+        }
+    }
 }
 }
 .errlable{
 .errlable{
     text-align: right;
     text-align: right;
@@ -182,7 +199,7 @@
 }
 }
 .left-box {
 .left-box {
     padding: 0px 70px;
     padding: 0px 70px;
-    height: 480px;
+    height: 430px;
     display: flex;
     display: flex;
     align-items: center;
     align-items: center;
     justify-content: center;
     justify-content: center;
@@ -194,7 +211,7 @@
     // box-shadow: -2px 0px 15px 0px rgba(75, 113, 136, 0.9);
     // box-shadow: -2px 0px 15px 0px rgba(75, 113, 136, 0.9);
     display: flex;
     display: flex;
     // align-items: center;
     // align-items: center;
-    height: 431px;
+    height: 380px;
     min-width: 600px;
     min-width: 600px;
 }
 }
 .student-login-img {
 .student-login-img {

+ 10 - 7
TEAMModelOS/ClientApp/src/view/login/page/Student.vue

@@ -116,10 +116,14 @@
 		<div class="left-box">
 		<div class="left-box">
 			<!-- 这张图片需要裁剪顶部 -->
 			<!-- 这张图片需要裁剪顶部 -->
 			<img src="@/assets/login/icon_student.svg" class="student-login-img" style="margin-top: -30px" />
 			<img src="@/assets/login/icon_student.svg" class="student-login-img" style="margin-top: -30px" />
-			<p class="client-label">
+			<p class="client-label" v-if="!queryCode">
 				{{ $t("login.stuCli") }}
 				{{ $t("login.stuCli") }}
 			</p>
 			</p>
 		</div>
 		</div>
+		<div class="query-school-info" v-if="queryCode">
+			<img :src="querySchoolInfo.picture" alt="" srcset="" width="60px" />
+			<span>{{ querySchoolInfo.name }}</span>
+		</div>
 		<div class="right-box">
 		<div class="right-box">
 			<!-- 醍摩豆表单登录 -->
 			<!-- 醍摩豆表单登录 -->
 			<div v-show="!qrloginFlag && !queryCode" class="tmd-login-box">
 			<div v-show="!qrloginFlag && !queryCode" class="tmd-login-box">
@@ -229,10 +233,9 @@
 			</div>
 			</div>
 			<!-- 校内账号登录 -->
 			<!-- 校内账号登录 -->
 			<div class="school-login-box">
 			<div class="school-login-box">
-				<div class="school-info" v-if="queryCode">
-					<img :src="querySchoolInfo.picture" alt="" srcset="" width="40px" />
-					<span>{{ querySchoolInfo.name }}</span>
-				</div>
+				<!-- <div class="school-info" v-if="queryCode">
+					{{ $t("login.stuCli") }}
+				</div> -->
 				<p class="teacher-login-title">{{ $t("login.title.schoolLogin") }}</p>
 				<p class="teacher-login-title">{{ $t("login.title.schoolLogin") }}</p>
 				<p class="teacher-login-decr">{{ $t("login.subTitle.schoolLogin") }}</p>
 				<p class="teacher-login-decr">{{ $t("login.subTitle.schoolLogin") }}</p>
 				<Form class="loginForm" ref="studForm" :model="studForm" :rules="studRule" :show-message="false" @keydown.enter.native="loginSubmit('studForm')">
 				<Form class="loginForm" ref="studForm" :model="studForm" :rules="studRule" :show-message="false" @keydown.enter.native="loginSubmit('studForm')">
@@ -264,9 +267,9 @@
 					<Checkbox v-model="isRememberForm" style="color: #fff; float: right">{{ $t("login.title.rememberPsw") }}</Checkbox>
 					<Checkbox v-model="isRememberForm" style="color: #fff; float: right">{{ $t("login.title.rememberPsw") }}</Checkbox>
 				</Form>
 				</Form>
 				<!-- 三方登录 -->
 				<!-- 三方登录 -->
-				<Divider class="login-divider" style="margin-top: 24px">{{ $t("login.communy.title") }}</Divider>
+				<Divider class="login-divider" style="margin-top: 34px">{{ $t("login.communy.title") }}</Divider>
 				<div class="other-login-box" style="margin-top: 0px; display: flex; flex-direction: column; align-items: center">
 				<div class="other-login-box" style="margin-top: 0px; display: flex; flex-direction: column; align-items: center">
-					<p style="color: #39d0e4; cursor: pointer" @click="queryCode = null" v-if="queryCode">{{ $t("schoolBaseInfo.goNormalLogin") }}</p>
+					<!-- <p style="color: #39d0e4; cursor: pointer" @click="queryCode = null" v-if="queryCode">{{ $t("schoolBaseInfo.goNormalLogin") }}</p> -->
 					<!-- 教育雲 -->
 					<!-- 教育雲 -->
 					<div class="other-login-item" @click="oauthLogin('educloudtwl')" v-if="srvAdr == 'Global'">
 					<div class="other-login-item" @click="oauthLogin('educloudtwl')" v-if="srvAdr == 'Global'">
 						<v-icon iconClass="educloudtw" class="icon-educlowudtw"></v-icon>
 						<v-icon iconClass="educloudtw" class="icon-educlowudtw"></v-icon>

+ 29 - 6
TEAMModelOS/Controllers/School/SchoolController.cs

@@ -32,6 +32,7 @@ using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models.Cosmos.BI;
 using TEAMModelOS.SDK.Models.Cosmos.BI;
 using TEAMModelOS.SDK.Models.Cosmos.School;
 using TEAMModelOS.SDK.Models.Cosmos.School;
 using TEAMModelOS.SDK.Models.Service.BI;
 using TEAMModelOS.SDK.Models.Service.BI;
+using static TEAMModelOS.SDK.Models.Teacher;
 
 
 namespace TEAMModelOS.Controllers
 namespace TEAMModelOS.Controllers
 {
 {
@@ -2243,11 +2244,32 @@ namespace TEAMModelOS.Controllers
         [ProducesDefaultResponseType]
         [ProducesDefaultResponseType]
         [HttpPost("get-area-iot")]
         [HttpPost("get-area-iot")]
         [Authorize(Roles = "IES")]
         [Authorize(Roles = "IES")]
-        [AuthToken(Roles = "admin")]
+        [AuthToken(Roles = "admin,teacher")]
         public async Task<IActionResult> getAreaIotData(JsonElement request)
         public async Task<IActionResult> getAreaIotData(JsonElement request)
         {
         {
             try
             try
             {
             {
+                //回傳值定義
+                IotStatisticsArea areaIot = new IotStatisticsArea(); //學區IOT統計結果
+                List<IotStatisticsSch> schoolIotResult = new List<IotStatisticsSch>(); //學校IOT統計結果
+                List<ProdAnalysisApiResult> iotData = new List<ProdAnalysisApiResult>(); //IOT資料
+                string err = string.Empty;
+                //取得ID
+                var (tmid, name, _, _school) = HttpContext.GetAuthTokenInfo();
+                if(string.IsNullOrWhiteSpace(tmid)) return BadRequest();
+                Teacher tmidInfo = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>(tmid, new PartitionKey("Base"));
+                //區管理者權限驗證 (有給areaId則驗)
+                string areaId = (request.TryGetProperty("areaId", out JsonElement _areaId)) ? _areaId.GetString() : string.Empty;
+                if(!string.IsNullOrWhiteSpace(areaId))
+                {
+                    TeacherArea hasAreaAdmin = tmidInfo.areas.Where(a => a.areaId.Equals(areaId)).FirstOrDefault();
+                    if(hasAreaAdmin == null || !hasAreaAdmin.status.Equals("join"))
+                    {
+                        err = "Permission denied.";
+                        return Ok(new { err, area = areaIot, school = schoolIotResult, iotData });
+                    }
+                }
+                //學校資料取得
                 if (!request.TryGetProperty("schoolIds", out JsonElement _schoolIds)) return BadRequest();
                 if (!request.TryGetProperty("schoolIds", out JsonElement _schoolIds)) return BadRequest();
                 List<string> schoolIds = _schoolIds.ToObject<List<string>>();
                 List<string> schoolIds = _schoolIds.ToObject<List<string>>();
                 List<string> periodIds = (request.TryGetProperty("periodIds", out JsonElement _periodIds)) ? _periodIds.ToObject<List<string>>() : new List<string>();
                 List<string> periodIds = (request.TryGetProperty("periodIds", out JsonElement _periodIds)) ? _periodIds.ToObject<List<string>>() : new List<string>();
@@ -2279,11 +2301,12 @@ namespace TEAMModelOS.Controllers
                         }
                         }
                     }
                     }
                 }
                 }
-                if (schools.Count.Equals(0)) return BadRequest();
+                if (schools.Count.Equals(0))
+                {
+                    return Ok(new { err, area = areaIot, school = schoolIotResult, iotData });
+                }
                 //取得各校IOT相關統計值
                 //取得各校IOT相關統計值
-                IotStatisticsArea areaIot = new IotStatisticsArea(); //學區IOT統計項
                 Dictionary<string, IotStatisticsSch> schIot = new Dictionary<string, IotStatisticsSch>(); //各校IOT統計項
                 Dictionary<string, IotStatisticsSch> schIot = new Dictionary<string, IotStatisticsSch>(); //各校IOT統計項
-                List<ProdAnalysisApiResult> iotData = new List<ProdAnalysisApiResult>(); //IOT資料
                 List<string> serialPermitList = new List<string>() { "J223IZ6M", "3222C6D2", "J223IZAM", "J2236ZCX", "3222DNG2", "3222IAVN", "BYJ6LZ6Z" };
                 List<string> serialPermitList = new List<string>() { "J223IZ6M", "3222C6D2", "J223IZAM", "J2236ZCX", "3222DNG2", "3222IAVN", "BYJ6LZ6Z" };
                 string serialPermitJsonStr = JsonConvert.SerializeObject(serialPermitList);
                 string serialPermitJsonStr = JsonConvert.SerializeObject(serialPermitList);
                 foreach (School school in schools)
                 foreach (School school in schools)
@@ -2429,7 +2452,7 @@ namespace TEAMModelOS.Controllers
                 }
                 }
 
 
                 //輸出整形
                 //輸出整形
-                List<IotStatisticsSch> schoolIotResult = new List<IotStatisticsSch>();
+                
                 foreach (KeyValuePair<string, IotStatisticsSch> schIotItem in schIot)
                 foreach (KeyValuePair<string, IotStatisticsSch> schIotItem in schIot)
                 {
                 {
                     IotStatisticsSch schIotData = schIotItem.Value;
                     IotStatisticsSch schIotData = schIotItem.Value;
@@ -2461,7 +2484,7 @@ namespace TEAMModelOS.Controllers
                     areaIot.lTypeDif += schIotData.lTypeDif;
                     areaIot.lTypeDif += schIotData.lTypeDif;
                 }
                 }
 
 
-                return Ok(new { area = areaIot, school = schoolIotResult, iotData });
+                return Ok(new { err, area = areaIot, school = schoolIotResult, iotData });
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {