Selaa lähdekoodia

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

jeff 4 vuotta sitten
vanhempi
commit
76c0b1ab1a

+ 5 - 0
TEAMModelOS/ClientApp/src/api/schoolSetting.js

@@ -63,5 +63,10 @@ export default {
     // Hiteach 與教室連接
     hiteachLink: function (data) {
         return post('/school/classroom/hiteach-link', data)
+    },
+
+    // 指定教室切斷 Hiteach 連接
+    hiteachUnlinkByClassId: function (data) {
+        return post('/school/classroom/hiteach-unlink-classId', data)
     }
 }

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

@@ -115,7 +115,7 @@
                                 icon: 'iconfont icon-class-mgt',
                                 name: '教室管理',
                                 router: '/home/classroom',
-                                tag: '*',
+                                tag: '',
                                 role: 'admin',
                                 permission: 'classroom-upd|classroom-read'
                             },

+ 2 - 2
TEAMModelOS/ClientApp/src/store/module/spaceAuth.js

@@ -145,12 +145,12 @@ export default {
 
         //模擬DB初值
         Object.defineProperty(element, "spaceInitValue", {
-          value: spaceValue,
+          value: element.size,
           writable: true,
         });
         //模擬接收讓使用者修改時的暫存值,留意input 進來會從數字變字串
         Object.defineProperty(element, "space", {
-          value: spaceValue,
+          value: element.size,
           writable: true,
         });
         //模擬存放各帳號目前變更的空間量

+ 35 - 29
TEAMModelOS/ClientApp/src/store/module/studentAclassOneAuth.js

@@ -1,34 +1,40 @@
 import apiTools from "@/api";
 export default {
-    namespaced: true,
-    state: {
-       
-    },
-    getters: {
-
-    },
-    mutations: {
+  namespaced: true,
+  state: {
+    schoolAclassOneInfoNum: undefined,
+  },
+  getters: {
+    getSchoolAclassOneInfoNum(state){
+        return state.schoolAclassOneInfoNum
+    }
+  },
+  mutations: {
+    setSchoolAclassOne(state, data) {
+      state.schoolAclassOneInfoNum = data;
+      console.log(state.schoolAclassOneInfoNum);
     },
-    actions: {
-        getSchoolAclassOne(schoolCode) {
-            return new Promise((resolve, reject) => {
-                apiTools.stuAccount.getSchoolAclassOne(schoolCode).then(
-                    (res)=>{
-                        console.log(res)
-                        resolve({
-                            code: 1,
-                            message: "Get AclassOne數量 API  successful",
-                          });
-                    },
-                    (err) => {
-                        reject({
-                          code: 0,
-                          data: [],
-                          message: "Get AclassOne數量 API error!",
-                        });
-                      }
-                )
+  },
+  actions: {
+    getSchoolAclassOne(context, schoolCode) {
+      return new Promise((resolve, reject) => {
+        apiTools.stuAccount.getSchoolAclassOne(schoolCode).then(
+          (res) => {
+            context.commit("setSchoolAclassOne", res);
+            resolve({
+              code: 1,
+              message: "Get AclassOne數量 API  successful",
             });
           },
-    }
-}
+          (err) => {
+            reject({
+              code: 0,
+              data: [],
+              message: "Get AclassOne數量 API error!",
+            });
+          }
+        );
+      });
+    },
+  },
+};

+ 39 - 2
TEAMModelOS/ClientApp/src/store/module/user.js

@@ -153,6 +153,7 @@ export default {
         getClasses: state => {
             return state.schoolProfile.school_classes
         }
+
     },
     mutations: {
         setSchoolUserList(state, data) {
@@ -226,6 +227,32 @@ export default {
         setSchoolCode(state, data) {
             state.schoolCode = data
         },
+        addClasses(state, data) {
+            let school_profile = localStorage.getItem('school_profile')
+            if(school_profile){
+                let schoolProfile = JSON.parse(decodeURIComponent(school_profile,"utf-8"))
+                schoolProfile.school_classes.unshift(data)
+                state.schoolProfile.school_classes = schoolProfile.school_classes
+                localStorage.setItem('school_profile', encodeURIComponent(JSON.stringify(schoolProfile), "utf-8"))
+            }
+        },
+        delClasses(state, id) {
+            let school_profile = localStorage.getItem('school_profile')
+            if(school_profile){
+                let schoolProfile = JSON.parse(decodeURIComponent(school_profile,"utf-8"))
+                let orgIndex = -1;
+
+                for (let i in schoolProfile.school_classes) {
+                    if (schoolProfile.school_classes[i].id == id) {
+                        orgIndex = i
+                        break
+                    }
+                }
+                schoolProfile.school_classes.splice(orgIndex, 1) // 刪掉指定教室
+                state.schoolProfile.school_classes = schoolProfile.school_classes
+                localStorage.setItem('school_profile', encodeURIComponent(JSON.stringify(schoolProfile), "utf-8"))
+            }
+        },
     },
     actions: {
 		// 获取学校基本信息
@@ -590,7 +617,7 @@ export default {
                 context.dispatch('setSchoolProfile', JSON.parse(decodeURIComponent(school_profile,"utf-8")))
             }
 
-            let login_schooCode = localStorage.getItem('login_schooCode')
+            let login_schoolCode = localStorage.getItem('login_schoolCode')
             let id_token = localStorage.getItem('id_token')
 
             if (login_schoolCode && id_token) {
@@ -690,6 +717,16 @@ export default {
                     )
                 }
             )
-        }
+        },
+        
+        // 新增教室
+        addSchoolClasses(context, data) {
+            context.commit('addClasses', data)
+        },
+
+        // 刪除教室
+        delSchoolClasses(context, id) {
+            context.commit('delClasses', id)
+        },
     }
 }

+ 74 - 68
TEAMModelOS/ClientApp/src/view/schoolmgmt/ClassroomSetting/ClassroomSetting.vue

@@ -144,9 +144,6 @@
                                         </Option>
                                     </Select>
                                 </FormItem>
-                                <FormItem>
-                                    <!-- <Button @click="testSave()">TEST</Button> -->
-                                    </FormItem>
                             </Form>
                         </vuescroll>
                     </div>
@@ -546,7 +543,7 @@
         computed: {
             ...mapGetters({
                 periods: 'user/getPeriods', // 學制s
-                aprules: 'schoolBaseInfo/getAprules',          
+                aprules: 'schoolBaseInfo/getAprules',
             }),            
             filterPeriodName: function(){
                 let data = this.periods
@@ -1008,17 +1005,60 @@
                                         this.$Message.error(res.v)
                                     } else {
 
-                                        // 修改Hiteach
-                                        
+                                        // Hiteach 與教室綁定
+                                        this.$api.schoolSetting.hiteachLink({
+                                            school_code: this.$store.state.userInfo.schoolCode,
+                                            linkList: this.updHiteachLink
+                                        }).then( hiteachLinkRes =>{
+                                            
+                                            if(hiteachLinkRes.error == 0){
+                                                let orgHiData = JSON.parse(this.orgHiteachData)
 
+                                                this.updHiteachLink.forEach(item => {
+                                                    let tempIndex;
+                                                    let temp = orgHiData.find( (hiItem, hiIndex) => {
+                                                        tempIndex = hiIndex
+                                                        return hiItem.id == item.id
+                                                    })
+                                                    if(temp.deviceBound != null && Array.isArray(temp.deviceBound) && temp.deviceBound.length > 0){
+                                                        temp.deviceBound.forEach( (dbItem, dbIndex, dbArray) => {
+                                                            if( (dbItem.uuid + dbItem.uuid2) == (item.uuid + item.uuid2)){
+                                                                dbItem.classId = item.classId
 
-                                        this.$Message.success(this.$t('schoolBaseInfo.csTips3'))                                        
-                                        this.updated = false
-                                        this.updHiteachLink = []
-                                        if (option == 'insert') {
-                                            this.classroomListShow[this.curClassIndex].code = 'Class-'+ this.classroomListShow[this.curClassIndex].code
-                                            this.classroomList.unshift(this.classroomListShow[this.curClassIndex])
-                                        }
+                                                                if(item.classId != null){
+                                                                    dbItem.hiteachLink = true
+                                                                } else {
+                                                                    dbItem.hiteachLink = false
+                                                                }
+                                                            }
+                                                        })
+
+                                                        orgHiData[tempIndex] = temp
+                                                    }
+                                                })
+                                                
+                                                // 原本API 內容
+                                                this.$Message.success(this.$t('schoolBaseInfo.csTips3'))                                        
+                                                this.updated = false
+                                                this.updHiteachLink = []
+                                                if (option == 'insert') {
+                                                    this.classroomListShow[this.curClassIndex].code = 'Class-'+ this.classroomListShow[this.curClassIndex].code
+                                                    this.classroomList.unshift(this.classroomListShow[this.curClassIndex])
+                                                    this.$store.dispatch('user/addSchoolClasses', this.classroomListShow[this.curClassIndex]);
+                                                }
+
+                                                // 新增加
+                                                this.hiteachData = orgHiData
+                                                this.orgHiteachData = JSON.stringify(orgHiData)
+                                            }
+                                        },err => {
+                                            this.$Message.error('Hiteach 綁定失敗!')
+                                        }).finally(
+                                            () => {
+                                                this.isSaveLoading = false
+                                                this.isListLoading = false
+                                            }
+                                        )
                                     }
                                     
                                 } else {
@@ -1028,7 +1068,8 @@
                             err => {
                                 this.$Message.error('API error!')
                             }
-                        ).finally(
+                        )
+                        .finally(
                             () => {
                                 this.isSaveLoading = false
                                 this.isListLoading = false
@@ -1080,7 +1121,6 @@
                     this.$Message.warning('您暂无次操作权限!')
                 }
             },
-
             delClassroom(index) {
                 this.isListLoading = true
                 if (this.classroomListShow[index].option !== 'insert') {
@@ -1102,21 +1142,13 @@
                                         break
                                     }
                                 }
-                                // 刪掉指定的classId
-                                let orgHiData = JSON.parse(this.orgHiteachData)
-                                orgHiData.forEach( item => {
-                                    if(Array.isArray(item.deviceBound) && item.deviceBound.length > 0){
-                                        item.deviceBound.forEach(db => {
-                                            if(db.classId == this.classroomListShow[index].id) {
-                                                db.classId = null
-                                                db.hiteachLink = false
-                                            }
-                                        })
-                                    }
+
+                                this.$api.schoolSetting.hiteachUnlinkByClassId({
+                                    classId: this.classroomListShow[index].id,
+                                    school_code: this.$store.state.userInfo.schoolCode
                                 })
-                                
-                                this.hiteachData = orgHiData
-                                this.orgHiteachData = JSON.stringify(orgHiData)
+                                this.unlinkHiteach(this.classroomListShow[index].id) // 刪掉指定的classId                                
+                                this.$store.dispatch('user/delSchoolClasses', this.classroomListShow[index].id);
 
                                 this.classroomList.splice(originIndex, 1)
                                 this.classroomListShow.splice(index, 1)
@@ -1138,11 +1170,11 @@
                         this.updateBefore = JSON.stringify(this.classroomListShow[this.curClassIndex])
                     }
                     this.classroomListShow.splice(index, 1)
+                    this.unlinkHiteach(this.classroomListShow[index].id)// 刪掉指定的classId
                     this.isListLoading = false
                     this.updated = false
                     this.updHiteachLink = []
                 }
-
             },
             uploadSchoolPlan(res, file) {
                 this.$Message.success(this.$t('schoolBaseInfo.csTips5'))
@@ -1399,49 +1431,23 @@
                             deviceId: item.deviceId
                         }
                     )
-                }                 
+                }
             },
-            testSave(){
-                // 給API
-                this.isListLoading = true
-                this.$api.schoolSetting.hiteachLink({
-                    school_code: this.$store.state.userInfo.schoolCode,
-                    linkList: this.updHiteachLink
-                }).then( res=>{
-                    
-                    if(res.error == 0){
-                        let orgHiData = JSON.parse(this.orgHiteachData)
-
-                        this.updHiteachLink.forEach(item => {
-                            let tempIndex;
-                            let temp = orgHiData.find( (hiItem, hiIndex) => {
-                                tempIndex = hiIndex
-                                return hiItem.id == item.id
-                            })
-                            if(temp.deviceBound != null && Array.isArray(temp.deviceBound) && temp.deviceBound.length > 0){
-                                temp.deviceBound.forEach( (dbItem, dbIndex, dbArray) => {
-                                    if( (dbItem.uuid + dbItem.uuid2) == (item.uuid + item.uuid2)){
-                                        dbItem.classId = item.classId
-
-                                        if(item.classId != null){
-                                            dbItem.hiteachLink = true
-                                        } else {
-                                            dbItem.hiteachLink = false
-                                        }
-                                    }
-                                })
-
-                                orgHiData[tempIndex] = temp
+            unlinkHiteach: function(classId){
+                // 刪掉指定的classId
+                let orgHiData = JSON.parse(this.orgHiteachData)
+                orgHiData.forEach( item => {
+                    if(Array.isArray(item.deviceBound) && item.deviceBound.length > 0){
+                        item.deviceBound.forEach(db => {
+                            if(db.classId == classId) {
+                                db.classId = null
+                                db.hiteachLink = false
                             }
                         })
-
-                        this.hiteachData = orgHiData
-                        this.orgHiteachData = JSON.stringify(orgHiData)
-                        this.updHiteachLink = []
-                        this.updated = false
-                        this.isListLoading = false
                     }
                 })
+                this.hiteachData = orgHiData
+                this.orgHiteachData = JSON.stringify(orgHiData)
             }
         },
         mounted() {

+ 2 - 2
TEAMModelOS/ClientApp/src/view/serviceDriveAuth/SubComponents/ServiceList.less

@@ -140,7 +140,7 @@
       .time-bar{
         background-color:  #4a4a4d;
         border-radius: 5px;
-        width:95%;
+       
         height: 4px;
         top:8px;
         position: relative;
@@ -148,7 +148,7 @@
       }
       .remain-bar{
         border-radius: 5px;
-        width:90%;
+       
         height: 4px;
         top:-4px;
         position: relative;

+ 4 - 5
TEAMModelOS/ClientApp/src/view/serviceDriveAuth/SubComponents/ServiceList.vue

@@ -38,9 +38,8 @@
         </p>
         <div v-if="item.hasOwnProperty('notbuy')!=true">
           <Row class="time-bar-wrap">
-            <i-col :xs="24" :sm="24" :md="24" :lg="16">
+            <i-col :xs="24" :sm="24" :md="24" :lg="16" style="padding-right:10px">
               <div class="time-bar" v-if="item.startDate != 0"></div>
-
               <div
                 class="remain-bar"
                 v-if="item.startDate != 0"
@@ -51,9 +50,9 @@
                         dateRemain(
                           converTime(item.startDate),
                           converTime(item.endDate)
-                        )) *
-                      100
-                    ).toFixed(2) + '%',
+                        )).toFixed(2) * 100
+                     
+                    ) + '%',
                   'background-color': colorPercent(
                     converTime(item.startDate),
                     converTime(item.endDate)

+ 51 - 20
TEAMModelOS/ClientApp/src/view/student-account/AclassOneAuth.vue

@@ -47,7 +47,7 @@
         <p class="info-num">
           <CountTo
             class="auth-info-num"
-            :endVal="pieNumData[1].value+pieNumData[0].value"
+            :endVal="usedAuth"
             :duration="600"
           ></CountTo>
         </p>
@@ -73,7 +73,7 @@
       <div v-if="currentTab == 0">
         <i-col :xs="24" :sm="12" :md="12" :lg="16">
           <p class="chart-title">
-            已購授權總數:<span class="chart-totalnum">356</span>
+            已購授權總數:<span class="chart-totalnum">{{totalAuth}}</span>
           </p>
           <AuthNumChart :clickTab="clickTab" :dbPieNumData="pieNumData" />
         </i-col>
@@ -339,8 +339,8 @@ export default {
       currentTab: 0,
       clickTab: false,
 
-      totalAuth: 356,
-      usedAuth: 128,
+      totalAuth: 0,
+      usedAuth: 0,
       currentAssignType: 0, //存放目前套用的類目 0為選,1當前選中,2選中並指定長度,3學制,4學籍,5班級,6全校
       currentAssignNum: 0, //存放目前所套用所選之數量
       currentFilter: -1, //當前所選中的篩選器
@@ -351,21 +351,25 @@ export default {
       basicCount: 99,
       pointNum: 0,
       pieNumData: [
-        { value: 104, name: "固定分配授權數" },
-        { value: 24, name: "今日動態取用數" },
-        { value: 228, name: "今日可用授權數" },
+        { value: 0, name: "固定分配授權數" },
+        { value: 0, name: "今日動態取用數" },
+        { value: 0, name: "今日可用授權數" },
       ],
 
       color: ["#eb974e", "#fb62bb", "#00f492"],
     };
   },
+  mounted(){
+    this.getSchoolAclassOne(this.$store.state.user.schoolCode);
   
+  },
   computed: {
     ...mapGetters({
       periods: "user/getPeriods", // 學制s
       grades: "user/getGrades", // 年級
       classes: "user/getClasses", // 教室ID
       //students: "schoolBaseInfo/getStudent", // 學生List
+      aclassOneInfoNum:"studentAclassOneAuth/getSchoolAclassOneInfoNum"
     }),
     filterGrades: function () {
       var data = this.grades;
@@ -394,9 +398,16 @@ export default {
     },
   },
   watch: {
-    //只要勾選有變動就預設套用第一項
-
-  
+    //只要勾選有變動就預設套用第一項,初始化時
+    aclassOneInfoNum:function(value){
+      if(value!=undefined){
+        this.totalAuth=value.total
+        this.usedAuth= value.staNum+value.dyncNum,
+        this.pieNumData[0].value=value.staNum
+        this.pieNumData[1].value=value.dyncNum
+        this.pieNumData[2].value=value.total-(this.pieNumData[1].value+this.pieNumData[0].value)
+      }
+    },
     selected: function (value) {
       this.currentAssignType = 1;
       //this.checkSelectIsAuth();
@@ -426,8 +437,8 @@ export default {
         });
 
         if (finalAdd <= this.totalAuth - this.usedAuth) {
-          this.usedAuth = this.usedAuth + finalAdd;
-          this.$Message.success("保存成功,本次新增" + finalAdd + "個");
+          this.usedAuth= this.usedAuth + finalAdd;
+          this.$Message.success("保存成功,本次新增" + finalAdd + "個,待API完善");
           this.$emit("updateAuth");
         } else {
           /*if (this.currentAssignNum <= (this.totalAuth - this.usedAuth)) {
@@ -455,8 +466,8 @@ export default {
         });
 
         if (finalAdd <= this.totalAuth - this.usedAuth) {
-          this.usedAuth = this.usedAuth + finalAdd;
-          this.$Message.success("保存成功,本次新增" + finalAdd + "個");
+           this.usedAuth= this.usedAuth + finalAdd;
+          this.$Message.success("保存成功,本次新增" + finalAdd + "個,待API完善");
           this.$emit("updateAuth");
         } else {
           this.$Message.error("保存失敗,超過可用授權數!");
@@ -476,16 +487,16 @@ export default {
           }
         });
         if (finalAdd <= this.totalAuth - this.usedAuth) {
-          this.usedAuth = this.usedAuth + finalAdd;
-          this.$Message.success("保存成功,本次新增" + finalAdd + "個");
+            this.usedAuth= this.usedAuth + finalAdd;
+          this.$Message.success("保存成功,本次新增" + finalAdd + "個,待API完善");
           this.$emit("updateAuth");
         } else {
           this.$Message.error("保存失敗,超過可用授權數!");
         }
       }
-      this.pieNumData[0].value = this.usedAuth;
+      this.pieNumData[0].value = this.usedAuth-this.aclassOneInfoNum.dyncNum;
 
-      this.pieNumData[2].value = this.totalAuth - this.usedAuth - 24;
+      this.pieNumData[2].value=this.aclassOneInfoNum.total-(this.pieNumData[1].value+this.pieNumData[0].value);
 
       this.currentFilter = -1;
       this.searchPeriod = "";
@@ -496,6 +507,26 @@ export default {
       this.inputSelectMax = "";
       this.currentAssignType = 0;
     },
+     //Louise API
+    getSchoolAclassOne(schoolCode) {
+      this.$store
+        .dispatch(
+          "studentAclassOneAuth/getSchoolAclassOne",
+          schoolCode
+        )
+        .then(
+          (res) => {
+           
+            this.isloading = false;
+            this.$Message.success("取得getSchoolAclassOne API資料");
+          },
+          (err) => {
+            this.$Message.error("取得getSchoolAclassOne API資料失敗");
+          }
+        );
+    },
+
+
     //Louise Mock 授權狀態
     resetAll() {
       this.usedAuth = 0;
@@ -505,12 +536,12 @@ export default {
       });
       this.$emit("updateAuth");
       this.isOpenRemove = false;
-      this.$Message.success("已收回全數授權!");
+      this.$Message.success("已收回全數授權!,待API完善");
 
       //重製餅圖
       this.pieNumData[0].value = 0;
       this.pieNumData[1].value = 0;
-      this.pieNumData[2].value = 356;
+      this.pieNumData[2].value = this.aclassOneInfoNum.total;
     },
     setStudentTarget(id) {
       let targetIndex = this.students.findIndex((item) => item.id == id);

+ 7 - 3
TEAMModelOS/ClientApp/src/view/student-account/AuthNumChart.vue

@@ -15,9 +15,13 @@ export default {
     };
   },
 
+  watch:{
+    dbPieNumData(val){
+      console.log(val)
+    }
+  },
   mounted() {
-    console.log(this.dbPieNumData);
-    //console.log( this.clickTab)
+    
     setTimeout(
       () => {
         this.drawLine(this.dbPieNumData);
@@ -191,7 +195,7 @@ export default {
         window.onresize = function () {
           myChart.resize();
         };
-      }, 200);
+      }, 100);
     },
   },
 };

+ 2 - 19
TEAMModelOS/ClientApp/src/view/student-account/Index.vue

@@ -776,23 +776,7 @@ export default {
       }
     },
 
-    //Louise API
-    getSchoolAclassOne(schoolCode) {
-      this.$store
-        .dispatch(
-          "studentAclassOneAuth/getSchoolAclassOne",
-          schoolCode
-        )
-        .then(
-          (res) => {
-            this.isloading = false;
-            this.$Message.success("取得getSchoolAclassOne API資料");
-          },
-          (err) => {
-            this.$Message.error("取得getSchoolAclassOne API資料失敗");
-          }
-        );
-    },
+   
 
     //Louise Mock 授權狀態
 
@@ -921,8 +905,7 @@ export default {
     },
   },
   mounted() {
-    this.getSchoolAclassOne(this.$store.state.user.schoolCode);
-    console.log(this.$store.state.user.schoolCode)
+   
     if (Array.isArray(this.periods)) {
       this.searchPeriod = this.periods[0].id;
     }

+ 4 - 4
TEAMModelOS/ClientApp/src/view/teachermgmt/components/userList/SubComponent/SpaceAuth.vue

@@ -210,17 +210,17 @@ export default {
       //input初步過濾負數與英文
       if (val == "") {
         this.$Message.warning("請手動輸入數字!");
-        this.multiAssignValue = 0;
+        this.multiAssignValue = '-';
       }
       //輸入的數字為浮點數
       if (this.isFloat(parseFloat(val)) == true) {
         this.$Message.warning("輸入了小數點,目前最小單位為1GB,請重新輸入!");
-        this.multiAssignValue = 0;
+        this.multiAssignValue = '-';
       }
        //輸入的數字為N.0
       if(val[val.length-1]=='0'&&val[val.length-2]=='.'){
         this.$Message.warning("輸入了小數點,目前最小單位為1GB,請重新輸入!");
-        this.multiAssignValue = 0;
+        this.multiAssignValue = '-';
       }
 
       //輸入的數字開頭為0
@@ -230,7 +230,7 @@ export default {
         val[0] == 0
       ) {
         this.$Message.warning("輸入了開頭為0的數字,請重新輸入!");
-        this.multiAssignValue = 0;
+        this.multiAssignValue = '-';
       }
     },
   },

+ 77 - 24
TEAMModelOS/Controllers/School/ClassRoomController.cs

@@ -423,17 +423,79 @@ namespace TEAMModelOS.Controllers
             if (!request.TryGetProperty("school_code", out JsonElement code)) return BadRequest();
             if (!request.TryGetProperty("linkList", out JsonElement links)) return BadRequest();
 
+            try
+            {
+                if (links.GetArrayLength() > 0) 
+                {
+                    // [變數宣告]
+                    string school_code = code.ToString(); // 學校簡碼
+                    JsonElement.ArrayEnumerator linkLists = request.GetProperty("linkList").EnumerateArray(); // 需要修改的資料
+                    int link_length = links.GetArrayLength(); // 需要修改的筆數
+
+                    // [取得DB資料]
+                    var client = _azureCosmos.GetCosmosClient();
+                    var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school_code, new PartitionKey("Product"));
+
+                    if (response.Status == 200)
+                    {
+                        var json = await JsonDocument.ParseAsync(response.ContentStream);
+
+                        //軟體
+                        SchoolProduct schoolProductItem = json.ToObject<SchoolProduct>();
+
+                        foreach (var linkList in linkLists)
+                        {
+                            var uuidBoolean = linkList.TryGetProperty("uuid", out var a);
+                            var uuid = a.GetString();
+
+                            var uuid2Boolean = linkList.TryGetProperty("uuid2", out var b);
+                            var uuid2 = b.GetString();
+
+                            var classIdBoolean = linkList.TryGetProperty("classId", out var c);
+                            var classId = c.GetString();
+
+                            var idBoolean = linkList.TryGetProperty("id", out var d);
+                            var id = d.GetString();
+
+                            SerialInfoBaseWithdeviceBound updSerialInfo = schoolProductItem.serial.Where(s => s.id == id).FirstOrDefault();
+                            if (updSerialInfo != null)
+                            {
+                                deviceBound updDeviceBound = updSerialInfo.deviceBound.Where(d => d.uuid == uuid && d.uuid2 == uuid2).FirstOrDefault();
+                                updDeviceBound.classId = classId;
+                            }
+                        }
+
+                        await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<SchoolProduct>(schoolProductItem, school_code, new PartitionKey("Product"));
+                    }
+                }
+                    
+                return Ok(new { error = 0 });
+            }
+            catch (Exception ex)
+            {
+               return BadRequest();
+            }
+        }
+
+        [ProducesDefaultResponseType]
+        //[AuthToken(Roles = "Teacher")]
+        [HttpPost("hiteach-unlink-classId")]
+        public async Task<IActionResult> HiteachUnlinkByClassId(JsonElement request)
+        {
+            // 必要檢查
+            if (!request.TryGetProperty("school_code", out JsonElement code)) return BadRequest();
+            if (!request.TryGetProperty("classId", out JsonElement id)) return BadRequest();
+
             try
             {
                 // [變數宣告]
                 string school_code = code.ToString(); // 學校簡碼
-                JsonElement.ArrayEnumerator linkLists = request.GetProperty("linkList").EnumerateArray(); // 需要修改的資料
-                int link_length = links.GetArrayLength(); // 需要修改的筆數
+                string classId = id.ToString(); // 教室ID
+
 
                 // [取得DB資料]
                 var client = _azureCosmos.GetCosmosClient();
-                //var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school_code, new PartitionKey("Product"));
-                var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync("hbcnOsbert", new PartitionKey("Product"));
+                var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school_code, new PartitionKey("Product"));
 
                 if (response.Status == 200)
                 {
@@ -442,36 +504,27 @@ namespace TEAMModelOS.Controllers
                     //軟體
                     SchoolProduct schoolProductItem = json.ToObject<SchoolProduct>();
 
-                    foreach (var linkList in linkLists)
+                    foreach (SerialInfoBaseWithdeviceBound updSerialInfo in schoolProductItem.serial) 
                     {
-                        var uuidBoolean = linkList.TryGetProperty("uuid", out var a);
-                        var uuid = a.GetString();
-
-                        var uuid2Boolean = linkList.TryGetProperty("uuid2", out var b);
-                        var uuid2 = b.GetString();
-
-                        var classIdBoolean = linkList.TryGetProperty("classId", out var c);
-                        var classId = c.GetString();
-
-                        var idBoolean = linkList.TryGetProperty("id", out var d);
-                        var id = d.GetString();
-
-                        SerialInfoBaseWithdeviceBound updSerialInfo = schoolProductItem.serial.Where(s => s.id == id).FirstOrDefault();
-                        if (updSerialInfo != null)
+                        if (updSerialInfo.deviceBound != null) 
                         {
-                            deviceBound updDeviceBound = updSerialInfo.deviceBound.Where(d => d.uuid == uuid && d.uuid2 == uuid2).FirstOrDefault();
-                            updDeviceBound.classId = classId;
+                            deviceBound updDeviceBound = updSerialInfo.deviceBound.Where(d => d.classId == classId).FirstOrDefault();
+                            if (updDeviceBound != null)
+                            {
+                                updDeviceBound.classId = null;
+                            }
                         }
+                        
                     }
 
-                    await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<SchoolProduct>(schoolProductItem, "hbcnOsbert", new PartitionKey("Product"));
+                    await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<SchoolProduct>(schoolProductItem, school_code, new PartitionKey("Product"));
                 }
-                
+
                 return Ok(new { error = 0 });
             }
             catch (Exception ex)
             {
-               return BadRequest();
+                return BadRequest();
             }
         }
     }

+ 1 - 1
TEAMModelOS/Controllers/School/SchoolTeacherController.cs

@@ -54,7 +54,7 @@ namespace TEAMModelOS.Controllers
             //string status_str = (request.TryGetProperty("join_status", out JsonElement status_json)) ? status_json.ToString() : "join";
             //資料取得
             List<object> teachers = new List<object>();
-            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: $"SELECT c.id, c.name, c.classes, c.picture ,c.status, c.job, c.createTime, ARRAY_LENGTH(c.permissions) as permissionCount FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school_code}") }))
+            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: $"SELECT c.id, c.name, c.classes, c.picture ,c.status, c.job, c.createTime, ARRAY_LENGTH(c.permissions) as permissionCount, c.size FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school_code}") }))
             {
                 using var json = await JsonDocument.ParseAsync(item.ContentStream);
                 if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)