ソースを参照

學校取得產品資訊 對應架構變更(前後端)(途中)

jeff 3 年 前
コミット
6edf280f80

+ 32 - 7
TEAMModelOS.SDK/Models/Cosmos/School/SchoolProduct.cs

@@ -62,7 +62,7 @@ namespace TEAMModelOS.SDK.Models
         public List<SchoolProductSumData> serial { get; set; }
         public List<SchoolProductSumData> service { get; set; }
         public List<SchoolProductSumDataHard> hard { get; set; }
-        //public Aclassone aclassone { get; set; } //是否獨立出來,未定
+        //public Aclassone aclassone { get; set; } //是否獨立出來,未定
     }
     public class SchoolProductSumProdInfo
     {
@@ -95,6 +95,31 @@ namespace TEAMModelOS.SDK.Models
         public string model { get; set; }
     }
 
+    //服務各產品資訊購買紀錄(前端用)
+    public class SchoolProductOrder
+    {
+        public string prodCode { get; set; }
+        public List<SchoolProductOrderList> order { get; set; }
+        public int avaliable { get; set; }
+        public long avaliableStartDate { get; set; }
+        public long avaliableEndDate { get; set; }
+    }
+    //產品購買紀錄
+    public class SchoolProductOrderList
+    {
+        public string id { get; set; }
+        public long startDate { get; set; }
+        public long endDate { get; set; }
+        public int number { get; set; }
+        public string unit { get; set; }
+    }
+
+
+    //序號資訊(含deviceId、classId、OS等硬體資訊)
+    public class SerialInfoBaseWithdeviceBoundExt : SchoolProductSerial
+    {
+        public new List<deviceBoundExt> deviceBound { get; set; }
+    }
 
     /////////////////////////////////////////////////////////
 
@@ -114,8 +139,8 @@ namespace TEAMModelOS.SDK.Models
 
     public class Aclassone
     {
-        public List<string> ids { get; set; } //固定分配的學生ID
-        public List<string> outids { get; set; } //過期被回收的學生ID(無法使用,待數量購足後回復移至ids)
+        public List<string> ids { get; set; } //固定分配的學生ID
+        public List<string> outids { get; set; } //過期被回收的學生ID(無法使用,待數量購足後回復移至ids)
         public int total { get; set; }
         public int used { get; set; }
     }
@@ -139,10 +164,10 @@ namespace TEAMModelOS.SDK.Models
     {
         public List<deviceBound> deviceBound { get; set; }
     }
-    public class SerialInfoBaseWithdeviceBoundExt : SerialInfoBase
-    {
-        public List<deviceBoundExt> deviceBound { get; set; }
-    }
+    //public class SerialInfoBaseWithdeviceBoundExt : SerialInfoBase
+    //{
+    //    public List<deviceBoundExt> deviceBound { get; set; }
+    //}
 
 
     public class deviceBound

+ 7 - 1
TEAMModelOS/ClientApp/src/locale/lang/en-US/serviceDriveAuth.js

@@ -5,6 +5,11 @@ export default {
   IPALYEIY: 'Smarter Teaching Service Space',
   '6BOPC6MD': 'Teaching and learning big data management services',
   ON6MBDOP: 'Smarter School Big Data Management Service',
+  IPALJ6NY: 'Smarter Teaching Service Space',
+  IPDYZYLC: 'Smarter School Management Module',
+  '3CLYJ6NP': 'AClass ONE',
+  YPMCJ6NC: 'Learning Analysis Module',
+  B9GPJ6NY: 'Sokrates Channel Management',
   服務授權列表: 'Service Authorization List',
   智慧教室授權管理: 'Smarter Classroom Authorization Management',
   未購買: 'Not Purchased',
@@ -65,7 +70,8 @@ export default {
   '到期後將變更為IES基本空間,超出基本空間值將被收回': 'After the expiration, it will be changed to the IES basic space and the value beyond the basic space will be withdrawn.',
   購買記錄: 'Purchase Record',
   醍摩豆智慧教學服務空間: 'TEAM Model Smarter Teaching Service Space',
-  訂單日期: 'Order Date: ',
+  訂單日期: 'Order Date:',
+  起始日: 'Start Date:',
   到期日: 'Expiry Date:',
   添購其他服務: 'Add Other Services',
   '空間已到期,超過僅供檢視': 'Space has expired, excess space is available for viewing only',

+ 6 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/serviceDriveAuth.js

@@ -5,6 +5,11 @@ export default {
   IPALYEIY: '智慧教学服务空间',
   '6BOPC6MD': '教与学大数据管理服务',
   ON6MBDOP: '智慧学校大数据管理服务',
+  IPALJ6NY: '数据储存服务空间',
+  IPDYZYLC: '智慧学校管理模组',
+  '3CLYJ6NP': 'AClass ONE',
+  YPMCJ6NC: '学情分析模组',
+  B9GPJ6NY: '苏格拉底频道管理',
   服務授權列表: '服务授权列表',
   智慧教室授權管理: '智慧教室授权管理',
   未購買: '未购买',
@@ -66,6 +71,7 @@ export default {
   購買記錄: '购买记录',
   醍摩豆智慧教学服務空間: '醍摩豆智慧教学服务空间',
   訂單日期: '订单日期:',
+  起始日: '起始日:',
   到期日: '到期日:',
   添購其他服務: '添购其他服务',
   '空間已到期,超過僅供檢視': '空间已到期,超过仅供检视',

+ 6 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/serviceDriveAuth.js

@@ -5,6 +5,11 @@ export default {
   IPALYEIY: '智慧教學服務空間',
   '6BOPC6MD': '教與學大數據管理服務',
   ON6MBDOP: '智慧學校大數據管理服務',
+  IPALJ6NY: '數據儲存服務空間',
+  IPDYZYLC: '智慧學校管理模組',
+  '3CLYJ6NP': 'AClass ONE',
+  YPMCJ6NC: '學情分析模組',
+  B9GPJ6NY: '蘇格拉底頻道管理',
   服務授權列表: '服務授權列表',
   智慧教室授權管理: '智慧教室授權管理',
   未購買: '未購買',
@@ -66,6 +71,7 @@ export default {
   購買記錄: '購買記錄',
   醍摩豆智慧教學服務空間: '醍摩豆智慧教學服務空間',
   訂單日期: '訂單日期:',
+  起始日: '起始日:',
   到期日: '到期日:',
   添購其他服務: '添購其他服務',
   '空間已到期,超過僅供檢視': '空間已到期,超過僅供檢視',

+ 53 - 27
TEAMModelOS/ClientApp/src/store/module/serviceDriveAuth.js

@@ -22,17 +22,22 @@ export default {
     //接實際api使用,一開始序號為空
 
     //第一區 服務清單
-    service: [],
+    service: [], //服務產品的購買紀錄
     seviceNameList: [
-      "ON6MBDOP",
-      "6BOPC6MD",
-      "IPALYEIY", //智慧教學服務空間
-      "RYGVCPLY",
-      "AEGMCPLY",
+      //"ON6MBDOP", //(V3)智慧學校大數據管理服務
+      //"6BOPC6MD", //(V3)教與學大數據管理服務
+      //"IPALYEIY", //(V3)智慧教學服務空間
+      //"RYGVCPLY", //(V3)AClass One 無週期
+      //"AEGMCPLY", //(V3)AClass One 週期
+        "IPALJ6NY", //(V5)數據儲存服務空間
+        "IPDYZYLC", //(V5)智慧學校管理模組
+        "3CLYJ6NP", //(V5)AClass ONE
+        "YPMCJ6NC", //(V5)學情分析模組
+        "B9GPJ6NY", //(V5)蘇格拉底頻道管理
     ],
 
     //第二區hiteach序號資料
-    serial: [],
+    serial: [], 
     serialInfo: {
       totalNum: 0,
       multiAuthNum: 0, //大量授權
@@ -43,6 +48,7 @@ export default {
 
     //第三區Space,由第一區的智慧教學服務空間的IPALYEIY
     space: {},
+
   },
   getters: {
     getServiceIntroIsOpen: (state) => {
@@ -84,6 +90,11 @@ export default {
         return {};
       }
     },
+    //取得某產品的購買紀錄
+    getServiceHistory: (state) => (prodCode) => {
+        return state.service.find(prod => prod.prodCode === prodCode).order;
+    },
+
     getTab(state){
       return state.currentTab
     }
@@ -147,7 +158,6 @@ export default {
     setSpaceStatus(state, data) {
       state.space = data;
     },
-
     
   },
   actions: {
@@ -192,11 +202,13 @@ export default {
 
 
 
-    //
+    //取得學校產品
     getSchoolProduct(context, schoolCode) {
       return new Promise((resolve, reject) => {
         apiTools.serviceDriveAuth.getSchoolProduct(schoolCode).then(
           (res) => {
+                console.log('getSchoolProduct res:')
+                console.log(res)
             let temp = [];
             for (let i = 0; i < res.serial.length; i++) {
               temp.push({
@@ -225,13 +237,15 @@ export default {
                 notbuy: true,
                 startDate: 0,
                 endDate: 0,
+                avaliableStartDate: 0,
+                avaliableEndDate: 0,
               })
             );
 
             let temp2 = [];
             for (let i = 0; i < res.service.length; i++) {
               //資料一進來,將AclassOne排在第一個
-              if (res.service[i].prodCode == "RYGVCPLY") {
+              if (res.service[i].prodCode == "3CLYJ6NP") {
                 res.service.unshift(res.service[i]);
                 res.service.splice(i + 1, 1);
               }
@@ -247,34 +261,46 @@ export default {
             context.commit("setServiceList", res.service);
 
             //提取空間資料
-            let space = res.service.filter(
-              (item) => item.prodCode == "IPALYEIY"
-            );
+            let space = res.spaceinfo;
 
-            Object.defineProperty(space[0], "totalused", {
+            Object.defineProperty(space, "totalused", {
               value:
-                space[0].doc +
-                space[0].image +
-                space[0].item +
-                space[0].other +
-                space[0].paper +
-                space[0].student +
-                space[0].teacher +
-                space[0].video,
+                space.doc +
+                space.image +
+                space.item +
+                space.other +
+                space.paper +
+                space.student +
+                space.teacher +
+                space.video +
+                space.audio +
+                space.vote +
+                space.survey +
+                space.record +
+                space.res,
               writable: true,
             });
-            Object.defineProperty(space[0], "unUsed", {
-              value: space[0].avaliable-space[0].totalused,
+            Object.defineProperty(space, "unUsed", {
+              value: space.avaliable-space.totalused,
               writable: true,
             });
 
-            Object.defineProperty(space[0], "unUsedPercent", {
-              value: ((space[0].unUsed/space[0].avaliable)*100).toFixed(2),
+            Object.defineProperty(space, "unUsedPercent", {
+              value: (space.avaliable != 0) ? ((space.unUsed/space.avaliable)*100).toFixed(2) : 0,
               writable: true,
             });
 
+            let spaceHistory = context.getters.getServiceHistory("IPALJ6NY");
+            if (typeof spaceHistory !== "undefined") {
+                Object.defineProperty(space, "history", {
+                    value: spaceHistory,
+                    writable: true,
+                });
+            }
+            
+
             console.log(space);
-            context.commit("setSpaceStatus", space[0]);
+            context.commit("setSpaceStatus", space); //寫入學校空間資訊
 
             resolve({
               code: 1,

+ 12 - 10
TEAMModelOS/ClientApp/src/view/serviceDriveAuth/SubComponents/ServiceList.vue

@@ -9,13 +9,13 @@
 
         </div>
         <div class="serviceList-wrap" :style="{ height: windowHeight - 116 + 'px' }">
-            <div class="service-item" v-for="(item, index) in serviceList" :key="index" v-show="item.prodCode != 'AEGMCPLY'">
+            <div class="service-item" v-for="(item, index) in serviceList" :key="index">
                 <div class="detail-btn" @click="setIntroOpen(index)">
                     <Icon v-show="serviceIntroIsOpen[index].isOpen == false" type="ios-arrow-down" />
                     <Icon v-show="serviceIntroIsOpen[index].isOpen == true" type="ios-arrow-up" />
                 </div>
                 <div v-for="(proName, index) in serviceNameList" :key="index">
-                    <p class="service-name" v-if="item.prodCode == proName && proName != 'AEGMCPLY'">
+                    <p class="service-name" v-if="item.prodCode == proName">
                         {{ $t(`serviceDriveAuth['${proName}']`) }}
                     </p>
                 </div>
@@ -24,9 +24,8 @@
 
                 <p class="nomal-text">
                     {{$t("serviceDriveAuth['服務啟用 / 到期日:']")}}
-                    <span class="strong-text" v-if="item.startDate != 0 && item.prodCode != 'RYGVCPLY'">{{ converTime(item.startDate) }} - {{ converTime(item.endDate) }}</span>
-                    <span class="strong-text" v-if="item.startDate == 0 && item.prodCode != 'RYGVCPLY'">--</span>
-                    <span class="strong-text" v-if="item.prodCode == 'RYGVCPLY' && isNaN(aclassOneTimeLimitData.startDate) == false">{{ converTime(aclassOneTimeLimitData.startDate) }} - {{ converTime(aclassOneTimeLimitData.endDate) }}</span>
+                    <span class="strong-text" v-if="item.avaliableStartDate != 0">{{ converTime(item.avaliableStartDate) }} - {{ converTime(item.avaliableEndDate) }}</span>
+                    <span class="strong-text" v-if="item.avaliableStartDate == 0 || isNaN(item.avaliableStartDate) == true">--</span>
                 </p>
                 <div v-if="item.hasOwnProperty('notbuy') != true">
                     <Row class="time-bar-wrap">
@@ -46,14 +45,14 @@
                     </Row>
                     <Row class="time-bar-wrap" v-if="isNaN(aclassOneTimeLimitData.startDate) == false">
                         <i-col :xs="24" :sm="24" :md="24" :lg="20" style="padding-right: 10px">
-                            <div class="time-bar" v-if="item.prodCode == 'RYGVCPLY'"></div>
-                            <div class="remain-bar" v-if="item.prodCode == 'RYGVCPLY'" :style="{
+                            <div class="time-bar" v-if="item.prodCode == '3CLYJ6NP'"></div>
+                            <div class="remain-bar" v-if="item.prodCode == '3CLYJ6NP'" :style="{
                   width: (dateRemain(today(), converTime(aclassOneTimeLimitData.endDate)) / dateRemain(converTime(aclassOneTimeLimitData.startDate), converTime(aclassOneTimeLimitData.endDate))).toFixed(2) * 100 + '%',
                   'background-color': colorPercent(converTime(aclassOneTimeLimitData.startDate), converTime(aclassOneTimeLimitData.endDate)) ? '#ad3435' : '#1cc0f3'
                 }"></div>
                         </i-col>
 
-                        <i-col :xs="24" :sm="24" :md="24" :lg="4" v-if="item.prodCode == 'RYGVCPLY'">
+                        <i-col :xs="24" :sm="24" :md="24" :lg="4" v-if="item.prodCode == '3CLYJ6NP'">
                             <span class="remainDay">{{$t("serviceDriveAuth['剩餘']")}}</span>
                             <span class="remainDay-text" :style="{
                   color: colorPercent(converTime(aclassOneTimeLimitData.startDate), converTime(aclassOneTimeLimitData.endDate)) ? '#ad3435' : '#1cc0f3'
@@ -158,19 +157,22 @@ export default {
         serviceList: function () {
             //根據服務的長度生出開關,只要服務數量變動就必須重置
             let temp = []
-
+            console.log('serviceList:');
+            console.log(this.serviceList);
             for (let i = 0; i < this.serviceList.length; i++) {
                 temp.push({
                     index: i,
                     isOpen: false
                 })
                 temp[0].isOpen = true //預設把AclassOne細節打開
-                if (this.serviceList[i].prodCode == 'AEGMCPLY' && this.serviceList[i].hasOwnProperty('notbuy') != true) {
+                if (this.serviceList[i].prodCode == '3CLYJ6NP' && this.serviceList[i].hasOwnProperty('notbuy') != true) {
                     //console.log(this.serviceList[i])
                     this.aclassOneTimeLimitData = this.serviceList[i]
                 }
             }
             this.serviceIntroIsOpen = temp
+            console.log('serviceIntroIsOpen:');
+            console.log(this.serviceIntroIsOpen);
         }
     },
     beforeRouteLeave(to, from, next) {

+ 13 - 11
TEAMModelOS/ClientApp/src/view/serviceDriveAuth/SubComponents/SpaceStatus.vue

@@ -68,11 +68,10 @@
       </i-col>
       <i-col :xs="24" :sm="24" :md="24" :lg="24">
         <p class="deadline-title">
-          {{$t("serviceDriveAuth['當前空間到期日']")}}<span class="deadline-time" v-if="totalavaliable>=totalused"
-            >{{ converTime(spaceStatus.endDate) }} ({{ remainDays }} {{$t("serviceDriveAuth['天']")}})</span
-          ><span v-else>{{$t("serviceDriveAuth['基本 1GB 永久授權']")}}</span>
+          {{$t("serviceDriveAuth['當前空間到期日']")}}
+          <span class="deadline-time" v-if="totalavaliable>=totalused">{{ converTime(spaceStatus.endDate) }} ({{ remainDays }} {{$t("serviceDriveAuth['天']")}})</span>
+          <span v-else>{{$t("serviceDriveAuth['基本 1GB 永久授權']")}}</span>
         </p>
-
         <p class="note" v-if="totalavaliable>=totalused">
           ( {{$t("serviceDriveAuth['到期後將變更為IES基本空間,超出基本空間值將被收回']")}} )
         </p>
@@ -112,8 +111,8 @@
               <Row s>
                 <i-col :xs="24" :sm="24" :md="24" :lg="12"
                   ><p class="nomal-text">
-                    {{$t("serviceDriveAuth['訂單日期']")}}<span class="strong-text">{{
-                      converTime(i.orderDate)
+                    {{$t("serviceDriveAuth['起始日']")}}<span class="strong-text">{{
+                      converTime(i.startDate)
                     }}</span>
                   </p></i-col
                 >
@@ -161,7 +160,7 @@ export default {
   },
   watch: {
     spaceStatus: function (value) {
-          console.log('spaceStatus')
+      console.log('spaceStatus')
       console.log(value)
       if (value !== undefined) {
         this.remainDays = this.dateRemain(
@@ -175,6 +174,7 @@ export default {
         this.unUsed = this.finalFormatNum(value.unUsed);
         this.unUsedText = this.finalFormatText(value.unUsed);
       }
+          console.log('remainDays:' + this.remainDays);
     },
   },
   methods: {
@@ -209,6 +209,9 @@ export default {
         return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
     },
     converTime: function (time) {
+      if (time == 0) {
+          return "--"
+      }
       //time: Unix timestamp(秒)
       let datetime = new Date();
       //let timerecount = time * 1000 - datetime.getTimezoneOffset() * 60 * 1000;
@@ -234,12 +237,11 @@ export default {
       return today;
     },
     dateRemain(today, endday) {
-     
-     
+      if (today == 0 || today == '--' || endday == 0 || endday == '--') {
+          return '--';
+      }
       let strEndday = endday.replace('.','/');
-
       //console.log(today, strEndday);
-
       let oDate1 = new Date(today);
       let oDate2 = new Date(strEndday);
       let iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 / 24); // 把相差的毫秒數轉換為天數

+ 385 - 171
TEAMModelOS/Controllers/School/SchoolController.cs

@@ -282,42 +282,60 @@ namespace TEAMModelOS.Controllers
         [HttpPost("get-school-product")]
         public async Task<IActionResult> GetSchoolProductInfo(JsonElement request)
         {
-            if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
-            var clientContainer = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School");
-
-            List<deviceBoundRich> serialDeviceUpdList = new List<deviceBoundRich>(); //要更新DB的序號內容
-            List<SerialInfoBaseWithdeviceBoundExt> serial = new List<SerialInfoBaseWithdeviceBoundExt>(); //最後要輸出的序號結果
-            List<object> service = new List<object>();
-            List<object> hard = new List<object>();
-            List<deviceForCoreService> uuidList = new List<deviceForCoreService>(); //要向CoreService詢問deviceID及硬體資訊的UUID列表
-            var response = await clientContainer.ReadItemStreamAsync(school_code.ToString(), new PartitionKey("Product"));
-            if (response.Status == 200)
+            try
             {
-                var json = await JsonDocument.ParseAsync(response.ContentStream);
+                if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
+                var clientContainer = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School");
+
+                List<SchoolProductSerial> serial = new List<SchoolProductSerial>(); //承接DB資料用:序號
+                List<SerialInfoBaseWithdeviceBoundExt> serialResult = new List<SerialInfoBaseWithdeviceBoundExt>(); //最後要輸出的序號結果
+                List<SchoolProductService> serviceProduct = new List<SchoolProductService>(); //承接DB資料用:服務
+                List<SchoolProductOrder> serviceOrder = new List<SchoolProductOrder>(); //服務各產品購買紀錄
+                List<SchoolProductSumData> serviceSum = new List<SchoolProductSumData>(); //服務各產品購買紀錄
+                List<SchoolProductHard> hard = new List<SchoolProductHard>(); //承接DB資料用:硬體
+                SchoolProductSum productSum = new SchoolProductSum(); //承接DB資料用:產品目前狀態 
+                List<SchoolProductSumProdInfo> prodinfo = new List<SchoolProductSumProdInfo>(); //產品資訊列表(名稱、八碼)
+                List<deviceForCoreService> uuidList = new List<deviceForCoreService>(); //要向CoreService詢問deviceID及硬體資訊的UUID列表
+                long UTCNow = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
+
+                ////取得各產品目前可得數量
+                var response = await clientContainer.ReadItemStreamAsync(school_code.ToString(), new PartitionKey($"ProductSum"));
+                if (response.Status == 200)
+                {
+                    using var json = await JsonDocument.ParseAsync(response.ContentStream);
+                    productSum = json.ToObject<SchoolProductSum>();
+                    prodinfo = productSum.prodinfo;
+                    serviceSum = productSum.service;
+                }
+
                 //軟體
-                if (json.RootElement.TryGetProperty("serial", out JsonElement serialJobj))
+                await foreach (var itemsr in clientContainer.GetItemQueryStreamIterator(queryText: $"SELECT * FROM c WHERE c.dataType = 'serial'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Product-{school_code}") }))
                 {
-                    foreach (var serialInfo in serialJobj.EnumerateArray())
+                    using var json = await JsonDocument.ParseAsync(itemsr.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                     {
-                        serial.Add(serialInfo.ToObject<SerialInfoBaseWithdeviceBoundExt>());
-                        if (serialInfo.TryGetProperty("deviceBound", out JsonElement deviceBoundJobj) && !string.IsNullOrWhiteSpace(deviceBoundJobj.ToString()))
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                         {
-                            foreach (var deviceBoundRow in deviceBoundJobj.EnumerateArray())
+                            serial.Add(obj.ToObject<SchoolProductSerial>());
+                            if (obj.TryGetProperty("deviceBound", out JsonElement deviceBoundJobj) && !string.IsNullOrWhiteSpace(deviceBoundJobj.ToString()))
                             {
-                                deviceForCoreService uuidForCore = new deviceForCoreService();
-                                uuidForCore.sn = (!string.IsNullOrWhiteSpace(Convert.ToString(serialInfo.GetProperty("serial")))) ? Convert.ToString(serialInfo.GetProperty("serial")) : null;
-                                uuidForCore.uuid1 = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("uuid")))) ? Convert.ToString(deviceBoundRow.GetProperty("uuid")) : null;
-                                uuidForCore.uuid2 = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("uuid2")))) ? Convert.ToString(deviceBoundRow.GetProperty("uuid2")) : null;
-                                uuidForCore.device_id = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("deviceId")))) ? Convert.ToString(deviceBoundRow.GetProperty("deviceId")) : null;
-                                uuidForCore.class_id = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("classId")))) ? Convert.ToString(deviceBoundRow.GetProperty("classId")) : null;
-                                uuidList.Add(uuidForCore);
+                                foreach (var deviceBoundRow in deviceBoundJobj.EnumerateArray())
+                                {
+                                    deviceForCoreService uuidForCore = new deviceForCoreService();
+                                    uuidForCore.sn = (!string.IsNullOrWhiteSpace(Convert.ToString(obj.GetProperty("serial")))) ? Convert.ToString(obj.GetProperty("serial")) : null;
+                                    uuidForCore.uuid1 = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("uuid")))) ? Convert.ToString(deviceBoundRow.GetProperty("uuid")) : null;
+                                    uuidForCore.uuid2 = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("uuid2")))) ? Convert.ToString(deviceBoundRow.GetProperty("uuid2")) : null;
+                                    uuidForCore.device_id = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("deviceId")))) ? Convert.ToString(deviceBoundRow.GetProperty("deviceId")) : null;
+                                    uuidForCore.class_id = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("classId")))) ? Convert.ToString(deviceBoundRow.GetProperty("classId")) : null;
+                                    uuidList.Add(uuidForCore);
+                                }
                             }
                         }
                     }
                 }
-                //取得DeviceInfo From Core
+                ////取得DeviceInfo From Core 並更新序號資料
                 List<deviceFromCoreService> coreUuidList = (List<deviceFromCoreService>)GetDeviceFromCoreAsync(uuidList).GetAwaiter().GetResult();
-                foreach (SerialInfoBaseWithdeviceBoundExt serialRow in serial)
+                foreach (SchoolProductSerial serialRow in serial)
                 {
                     var deviceBoundArray = new List<deviceBoundExt>();
                     List<deviceFromCoreService> coreUuid = coreUuidList
@@ -339,183 +357,379 @@ namespace TEAMModelOS.Controllers
                         deviceBoundExt.osver = deviceRow.os_ver;
                         deviceBoundArray.Add(deviceBoundExt);
                         //DB更新用
-                        deviceBound serialDeviceBoundRow = serialRow.deviceBound.Where(d => d.uuid == deviceBoundRow.uuid1 && d.uuid2 == deviceBoundRow.uuid2).FirstOrDefault();
-                        if (serialDeviceBoundRow.deviceId != deviceRow.device_id)
+                        deviceBound serialDeviceBoundRow = serialRow.deviceBound.Where(d => (d.uuid == deviceBoundRow.uuid1 && d.uuid2 == deviceBoundRow.uuid2) || (d.uuid == deviceBoundRow.uuid2 && d.uuid2 == deviceBoundRow.uuid1)).FirstOrDefault();
+                        if (serialDeviceBoundRow != null)
                         {
-                            deviceBoundRich deviceBoundUpdRow = new deviceBoundRich();
-                            deviceBoundUpdRow.serial = deviceRow.sn;
-                            deviceBoundUpdRow.uuid = deviceBoundRow.uuid1;
-                            deviceBoundUpdRow.uuid2 = deviceBoundRow.uuid2;
-                            deviceBoundUpdRow.classId = deviceBoundRow.class_id;
-                            deviceBoundUpdRow.deviceId = deviceRow.device_id;
-                            serialDeviceUpdList.Add(deviceBoundUpdRow);
+                            serialDeviceBoundRow.deviceId = deviceRow.device_id;
                         }
                     }
-                    serialRow.deviceBound = deviceBoundArray;
+                    //序號更新
+                    await clientContainer.ReplaceItemAsync<SchoolProductSerial>(serialRow, serialRow.id, new PartitionKey($"Product-{school_code}"));
+                    //回傳值
+                    SerialInfoBaseWithdeviceBoundExt serialResultRow = new SerialInfoBaseWithdeviceBoundExt();
+                    serialResultRow.serial = serialRow.serial;
+                    serialResultRow.clientQty = serialRow.clientQty;
+                    serialResultRow.regDate = serialRow.regDate;
+                    serialResultRow.startDate = serialRow.startDate;
+                    serialResultRow.endDate = serialRow.endDate;
+                    serialResultRow.deviceMax = serialRow.deviceMax;
+                    serialResultRow.aprule = serialRow.aprule;
+                    serialResultRow.expireStatus = serialRow.expireStatus;
+                    serialResultRow.status = serialRow.status;
+                    serialResultRow.deviceBound = deviceBoundArray;
+                    serialResult.Add(serialResultRow);
                 }
 
                 //服務
-                if (json.RootElement.TryGetProperty("service", out JsonElement serviceJobj) && serviceJobj.ValueKind != JsonValueKind.Null)
+                bool buySpaceFlg = false;
+                ////取得學校空間使用狀況
+                var blobClient = _azureStorage.GetBlobContainerClient(school_code.ToString());
+                long? docSize = await blobClient.GetBlobsSize("doc");
+                long? imageSize = await blobClient.GetBlobsSize("image");
+                long? resSize = await blobClient.GetBlobsSize("res");
+                long? videoSize = await blobClient.GetBlobsSize("video");
+                long? audioSize = await blobClient.GetBlobsSize("audio");
+                long? examSize = await blobClient.GetBlobsSize("exam");
+                long? voteSize = await blobClient.GetBlobsSize("vote");
+                long? surveySize = await blobClient.GetBlobsSize("survey");
+                long? itemSize = await blobClient.GetBlobsSize("item");
+                long? paperSize = await blobClient.GetBlobsSize("paper");
+                long? syllabusSize = await blobClient.GetBlobsSize("syllabus");
+                long? avatarSize = await blobClient.GetBlobsSize("avatar");
+                long? recordSize = await blobClient.GetBlobsSize("records");
+                long? otherSize = await blobClient.GetBlobsSize("other");
+                long? studentSize = await blobClient.GetBlobsSize("student");
+                long teacherSize = 0;
+                ////取得教師分配空間
+                var querysp = $"SELECT SUM(c.size) as size FROM c";
+                await foreach (var item in clientContainer.GetItemQueryStreamIterator(queryText: querysp, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school_code}") }))
                 {
-                    //取得active的主週期、所有主週期歷史
-                    List<ServiceMainPeriod> activeMainPeriod = new List<ServiceMainPeriod>();
-                    List<ServiceMainPeriod> historyMainPeriod = new List<ServiceMainPeriod>();
-                    //ServiceMainPeriod activeMainPeriod = new ServiceMainPeriod();
-                    if (serviceJobj.TryGetProperty("mainperiod", out JsonElement mainperiodJobj))
+                    var jsonts = await JsonDocument.ParseAsync(item.ContentStream);
+                    foreach (var obj in jsonts.RootElement.GetProperty("Documents").EnumerateArray())
                     {
-                        foreach (var mainperiodRow in mainperiodJobj.EnumerateArray())
-                        {
-                            historyMainPeriod.Add(mainperiodRow.ToObject<ServiceMainPeriod>());
-                            if (mainperiodRow.GetProperty("active").GetBoolean())
-                            {
-                                activeMainPeriod.Add(mainperiodRow.ToObject<ServiceMainPeriod>());
-                            }
-                        }
+                        teacherSize = obj.GetProperty("size").GetInt64() * 1073741824;//G換算成bytes
                     }
-
-                    //取得active主週期的副週期
-                    List<ServicePeriod> activePeriodOfMain = new List<ServicePeriod>();
-                    List<ServicePeriod> historyPeriodOfMain = new List<ServicePeriod>();
-                    if (serviceJobj.TryGetProperty("period", out JsonElement periodJobj))
+                }
+                dynamic spaceinfo = new ExpandoObject();
+                spaceinfo.doc = docSize;
+                spaceinfo.video = videoSize;
+                spaceinfo.image = imageSize;
+                spaceinfo.res = resSize;
+                spaceinfo.video = voteSize;
+                spaceinfo.audio = audioSize;
+                spaceinfo.vote = voteSize;
+                spaceinfo.survey = surveySize;
+                spaceinfo.item = itemSize;
+                spaceinfo.paper = paperSize;
+                spaceinfo.syllabus = syllabusSize;
+                spaceinfo.avatar = avatarSize;
+                spaceinfo.record = recordSize;
+                spaceinfo.other = otherSize;
+                spaceinfo.student = studentSize;
+                spaceinfo.teacher = teacherSize;
+                SchoolProductSumData spaceDum = serviceSum.Where(svsum => svsum.prodCode.Equals("IPALJ6NY")).FirstOrDefault(); //取得目前學校空間可用數
+                spaceinfo.avaliable = (spaceDum != null) ? spaceDum.avaliable : 0;
+                spaceinfo.startDate = 0;
+                spaceinfo.endDate = 0;
+                ////(服務)取得各產品購買履歷
+                await foreach (var itemsv in clientContainer.GetItemQueryStreamIterator(queryText: $"SELECT * FROM c WHERE c.dataType = 'service'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Product-{school_code}") }))
+                {
+                    using var json = await JsonDocument.ParseAsync(itemsv.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                     {
-                        foreach (var periodRow in periodJobj.EnumerateArray())
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                         {
-                            historyPeriodOfMain.Add(periodRow.ToObject<ServicePeriod>());
-                            foreach (ServiceMainPeriod mainPeriodRow in activeMainPeriod)
+                            SchoolProductService serviceProductRow = obj.ToObject<SchoolProductService>();
+                            serviceProduct.Add(serviceProductRow);
+                            //學校空間特別處理:取得起始結束時間
+                            if (serviceProductRow.code.Equals("IPALJ6NY"))
                             {
-                                if (periodRow.GetProperty("mainPeriodId").ToString() == mainPeriodRow.mainPeriodId)
+                                if(serviceProductRow.startDate < UTCNow && UTCNow < serviceProductRow.endDate)
                                 {
-                                    activePeriodOfMain.Add(periodRow.ToObject<ServicePeriod>());
+                                    spaceinfo.startDate = serviceProductRow.startDate;
+                                    spaceinfo.endDate = serviceProductRow.endDate;
                                 }
                             }
                         }
                     }
-                    //計算各產品時間區域
-                    bool buySpaceFlg = false;
-                    ////取得學校空間使用狀況
-                    var blobClient = _azureStorage.GetBlobContainerClient(school_code.ToString());
-                    long? docSize = await blobClient.GetBlobsSize("doc");
-                    long? videoSize = await blobClient.GetBlobsSize("video");
-                    long? imageSize = await blobClient.GetBlobsSize("image");
-                    long? paperSize = await blobClient.GetBlobsSize("paper");
-                    long? itemSize = await blobClient.GetBlobsSize("item");
-                    long? otherSize = await blobClient.GetBlobsSize("other");
-                    long? studentSize = await blobClient.GetBlobsSize("student");
-                    long teacherSize = 0;
-                    if (serviceJobj.TryGetProperty("product", out JsonElement serviceProductJobj))
+                }
+                ////(服務)產品購買履歷整形
+                IEnumerable<SchoolProductService> serviceProductOrder = serviceProduct.OrderBy(sp => sp.startDate);
+                foreach(SchoolProductService serviceProductRow in serviceProduct)
+                {
+                    //取得此產品現在可用數
+                    SchoolProductSumData serviceSumNow = serviceSum.Where(ss => ss.prodCode.Equals(serviceProductRow.prodCode)).FirstOrDefault();
+                    int serviceAvaliableNow = (serviceSumNow != null) ? serviceSumNow.avaliable : 0;
+                    //取得此產品購買履歷
+                    SchoolProductOrder serviceOrderNow = serviceOrder.Where(so => so.prodCode == serviceProductRow.prodCode).FirstOrDefault();
+                    if(serviceOrderNow == null) //無此產品項
                     {
-
-                        foreach (var serviceProductRow in serviceProductJobj.EnumerateArray())
+                        SchoolProductOrder serviceOrderRow = new SchoolProductOrder();
+                        serviceOrderRow.prodCode = serviceProductRow.prodCode;
+                        serviceOrderRow.order = new List<SchoolProductOrderList>();
+                        SchoolProductOrderList serviceOrderRowOrderList = new SchoolProductOrderList();
+                        serviceOrderRowOrderList.id = serviceProductRow.id;
+                        serviceOrderRowOrderList.startDate = serviceProductRow.startDate;
+                        serviceOrderRowOrderList.endDate = serviceProductRow.endDate;
+                        serviceOrderRowOrderList.number = serviceProductRow.number;
+                        serviceOrderRowOrderList.unit = serviceProductRow.unit;
+                        serviceOrderRow.order.Add(serviceOrderRowOrderList);
+                        serviceOrderRow.avaliable = serviceAvaliableNow;
+                        if (serviceProductRow.startDate < UTCNow && UTCNow < serviceProductRow.endDate)
                         {
-                            ServiceProductResult serviceProductResultRow = CalServiceProductAuth(activeMainPeriod, activePeriodOfMain, serviceProductRow.ToObject<ServiceProduct>());
-                            if (!string.IsNullOrWhiteSpace(serviceProductResultRow.prodCode))
-                            {
-                                switch (serviceProductResultRow.prodCode)
-                                {
-                                    case "RYGVCPLY": //AClassOne買斷、週期
-                                    case "AEGMCPLY":
-                                        ServiceProductAclassoneResult serviceProductAclassoneResult = new ServiceProductAclassoneResult();
-                                        serviceProductAclassoneResult.prodCode = serviceProductResultRow.prodCode;
-                                        serviceProductAclassoneResult.noperiod = serviceProductResultRow.noperiod;
-                                        serviceProductAclassoneResult.serviceType = serviceProductResultRow.serviceType;
-                                        serviceProductAclassoneResult.startDate = serviceProductResultRow.startDate;
-                                        serviceProductAclassoneResult.endDate = serviceProductResultRow.endDate;
-                                        serviceProductAclassoneResult.avaliable = serviceProductResultRow.avaliable;
-                                        serviceProductAclassoneResult.staUsed = 0;
-                                        serviceProductAclassoneResult.dynUsed = 0;
-                                        if (json.RootElement.TryGetProperty("aclassone", out JsonElement aclassoneJobj) && aclassoneJobj.ValueKind != JsonValueKind.Null)
-                                        {
-                                            int total = (aclassoneJobj.TryGetProperty("total", out JsonElement totalJobj)) ? totalJobj.GetInt32() : 0;
-                                            serviceProductAclassoneResult.staUsed = (aclassoneJobj.TryGetProperty("used", out JsonElement usedJobj)) ? usedJobj.GetInt32() : 0; //固定分配數
-                                            List<string> dyncIdList = GetSchoolDynamicAclassOneIDList(school_code.GetString()); //動態使用ID
-                                            serviceProductAclassoneResult.dynUsed = dyncIdList.Count;
-                                        }
-                                        service.Add(serviceProductAclassoneResult);
-                                        break;
-                                    case "IPALYEIY": //智慧教學服務空間
-                                        ////取得目前使用狀況
-                                        //取得教師分配空間
-                                        var query = $"SELECT SUM(c.size) as size FROM c";
-                                        await foreach (var item in clientContainer.GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school_code}") }))
-                                        {
-                                            var jsonts = await JsonDocument.ParseAsync(item.ContentStream);
-                                            foreach (var obj in jsonts.RootElement.GetProperty("Documents").EnumerateArray())
-                                            {
-                                                teacherSize = obj.GetProperty("size").GetInt64() * 1073741824;//G換算成bytes
-                                            }
-                                        }
-                                        //欄位取得
-                                        dynamic serviceSpaceProductInfo = new ExpandoObject();
-                                        serviceSpaceProductInfo.prodCode = serviceProductResultRow.prodCode;
-                                        serviceSpaceProductInfo.noperiod = serviceProductResultRow.noperiod;
-                                        serviceSpaceProductInfo.serviceType = serviceProductResultRow.serviceType;
-                                        serviceSpaceProductInfo.startDate = serviceProductResultRow.startDate;
-                                        serviceSpaceProductInfo.endDate = serviceProductResultRow.endDate;
-                                        serviceSpaceProductInfo.avaliable = (long)(serviceProductResultRow.avaliable + this.baseSpaceSize) * 1073741824; //G換算成bytes
-                                        serviceSpaceProductInfo.doc = docSize;
-                                        serviceSpaceProductInfo.video = videoSize;
-                                        serviceSpaceProductInfo.image = imageSize;
-                                        serviceSpaceProductInfo.paper = paperSize;
-                                        serviceSpaceProductInfo.item = itemSize;
-                                        serviceSpaceProductInfo.other = otherSize;
-                                        serviceSpaceProductInfo.student = studentSize;
-                                        serviceSpaceProductInfo.teacher = teacherSize;
-                                        serviceSpaceProductInfo.history = CalServiceProductOrderHistory(historyMainPeriod, historyPeriodOfMain, serviceProductRow.ToObject<ServiceProduct>()); ////購買紀錄
-                                        service.Add(serviceSpaceProductInfo);
-                                        buySpaceFlg = true;
-                                        break;
-                                    default:
-                                        service.Add(serviceProductResultRow);
-                                        break;
-                                }
-                            }
+                            serviceOrderRow.avaliableStartDate = serviceProductRow.startDate;
+                            serviceOrderRow.avaliableEndDate = serviceProductRow.endDate;
                         }
+                        serviceOrder.Add(serviceOrderRow);
                     }
-                    //學校保底空間追加
-                    if (!buySpaceFlg) //未購買任何空間
+                    else //有此產品項 => 看是否有此購買紀錄
                     {
-                        dynamic serviceSpaceProductInfo = new ExpandoObject();
-                        serviceSpaceProductInfo.prodCode = "IPALYEIY";
-                        serviceSpaceProductInfo.noperiod = false;
-                        serviceSpaceProductInfo.serviceType = "space";
-                        serviceSpaceProductInfo.startDate = 0;
-                        serviceSpaceProductInfo.endDate = 0;
-                        serviceSpaceProductInfo.avaliable = this.baseSpaceSize * 1073741824; //1G換算成bytes
-                        serviceSpaceProductInfo.doc = docSize;
-                        serviceSpaceProductInfo.video = videoSize;
-                        serviceSpaceProductInfo.image = imageSize;
-                        serviceSpaceProductInfo.paper = paperSize;
-                        serviceSpaceProductInfo.item = itemSize;
-                        serviceSpaceProductInfo.other = otherSize;
-                        serviceSpaceProductInfo.student = studentSize;
-                        serviceSpaceProductInfo.teacher = teacherSize;
-                        serviceSpaceProductInfo.history = null;
-                        service.Add(serviceSpaceProductInfo);
+                        //記入可用起始終止日
+                        if (serviceProductRow.startDate < UTCNow && UTCNow < serviceProductRow.endDate)
+                        {
+                            serviceOrderNow.avaliableStartDate = serviceProductRow.startDate;
+                            serviceOrderNow.avaliableEndDate = serviceProductRow.endDate;
+                        }
+                        //記入購買紀錄
+                        SchoolProductOrderList SchoolProductOrderListNow = serviceOrderNow.order.Where(Sol => Sol.id.Equals(serviceProductRow.id)).FirstOrDefault();
+                        if (SchoolProductOrderListNow == null) //無此購買紀錄
+                        {
+                            SchoolProductOrderList serviceOrderRowOrderList = new SchoolProductOrderList();
+                            serviceOrderRowOrderList.id = serviceProductRow.id;
+                            serviceOrderRowOrderList.startDate = serviceProductRow.startDate;
+                            serviceOrderRowOrderList.endDate = serviceProductRow.endDate;
+                            serviceOrderRowOrderList.number = serviceProductRow.number;
+                            serviceOrderRowOrderList.unit = serviceProductRow.unit;
+                            serviceOrderNow.order.Add(serviceOrderRowOrderList);
+                        }
                     }
                 }
-
                 //硬體
-                if (json.RootElement.TryGetProperty("hard", out JsonElement hardJobj) && hardJobj.ValueKind != JsonValueKind.Null)
+                await foreach (var itemhd in clientContainer.GetItemQueryStreamIterator(queryText: $"SELECT * FROM c WHERE c.dataType = 'hard'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Product-{school_code}") }))
                 {
-                    hard.Add(hardJobj.ToObject<object>());
-                }
-
-                //更新DB
-                if (serialDeviceUpdList.Count > 0)
-                {
-                    SchoolProduct schoolProductItem = json.ToObject<SchoolProduct>();
-                    foreach (deviceBoundRich serialDeviceUpdRow in serialDeviceUpdList)
+                    using var json = await JsonDocument.ParseAsync(itemhd.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                     {
-                        SerialInfoBaseWithdeviceBound updSerialInfo = schoolProductItem.serial.Where(s => s.serial == serialDeviceUpdRow.serial).FirstOrDefault();
-                        deviceBound updDeviceBound = updSerialInfo.deviceBound.Where(d => d.uuid == serialDeviceUpdRow.uuid && d.uuid2 == serialDeviceUpdRow.uuid2).FirstOrDefault();
-                        updDeviceBound.deviceId = serialDeviceUpdRow.deviceId;
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        {
+                            hard.Add(obj.ToObject<SchoolProductHard>());
+                        }
                     }
-                    await clientContainer.ReplaceItemAsync<SchoolProduct>(schoolProductItem, schoolProductItem.id, new PartitionKey("Product"));
                 }
 
+                return Ok(new { prodinfo, serial = serialResult, service = serviceOrder, hard, spaceinfo });
             }
+            catch (Exception ex)
+            {
+                return BadRequest();
+            }
+
+            //var response = await clientContainer.ReadItemStreamAsync(school_code.ToString(), new PartitionKey($"Product-{school_code}"));
+            //if (response.Status == 200)
+            //{
+            //    var json = await JsonDocument.ParseAsync(response.ContentStream);
+            //    //軟體
+            //    if (json.RootElement.TryGetProperty("serial", out JsonElement serialJobj))
+            //    {
+            //        foreach (var serialInfo in serialJobj.EnumerateArray())
+            //        {
+            //            serial.Add(serialInfo.ToObject<SerialInfoBaseWithdeviceBoundExt>());
+            //            if (serialInfo.TryGetProperty("deviceBound", out JsonElement deviceBoundJobj) && !string.IsNullOrWhiteSpace(deviceBoundJobj.ToString()))
+            //            {
+            //                foreach (var deviceBoundRow in deviceBoundJobj.EnumerateArray())
+            //                {
+            //                    deviceForCoreService uuidForCore = new deviceForCoreService();
+            //                    uuidForCore.sn = (!string.IsNullOrWhiteSpace(Convert.ToString(serialInfo.GetProperty("serial")))) ? Convert.ToString(serialInfo.GetProperty("serial")) : null;
+            //                    uuidForCore.uuid1 = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("uuid")))) ? Convert.ToString(deviceBoundRow.GetProperty("uuid")) : null;
+            //                    uuidForCore.uuid2 = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("uuid2")))) ? Convert.ToString(deviceBoundRow.GetProperty("uuid2")) : null;
+            //                    uuidForCore.device_id = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("deviceId")))) ? Convert.ToString(deviceBoundRow.GetProperty("deviceId")) : null;
+            //                    uuidForCore.class_id = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundRow.GetProperty("classId")))) ? Convert.ToString(deviceBoundRow.GetProperty("classId")) : null;
+            //                    uuidList.Add(uuidForCore);
+            //                }
+            //            }
+            //        }
+            //    }
+            //    //取得DeviceInfo From Core
+            //    List<deviceFromCoreService> coreUuidList = (List<deviceFromCoreService>)GetDeviceFromCoreAsync(uuidList).GetAwaiter().GetResult();
+            //    foreach (SerialInfoBaseWithdeviceBoundExt serialRow in serial)
+            //    {
+            //        var deviceBoundArray = new List<deviceBoundExt>();
+            //        List<deviceFromCoreService> coreUuid = coreUuidList
+            //               .Where((deviceFromCoreService x) => x.sn == serialRow.serial)
+            //               .ToList();
+            //        foreach (deviceFromCoreService deviceRow in coreUuid)
+            //        {
+            //            //前端顯示用
+            //            deviceForCoreService deviceBoundRow = uuidList.Where(u => u.sn == deviceRow.sn && u.uuid1 == deviceRow.uuid1 && u.uuid2 == deviceRow.uuid2).FirstOrDefault();
+            //            deviceBoundExt deviceBoundExt = new deviceBoundExt();
+            //            deviceBoundExt.uuid = deviceBoundRow.uuid1;
+            //            deviceBoundExt.uuid2 = deviceBoundRow.uuid2;
+            //            deviceBoundExt.classId = deviceBoundRow.class_id;
+            //            deviceBoundExt.deviceId = deviceRow.device_id;
+            //            deviceBoundExt.os = deviceRow.os;
+            //            deviceBoundExt.ip = deviceRow.local_ip;
+            //            deviceBoundExt.cpu = deviceRow.cpu;
+            //            deviceBoundExt.pcname = deviceRow.pc_name;
+            //            deviceBoundExt.osver = deviceRow.os_ver;
+            //            deviceBoundArray.Add(deviceBoundExt);
+            //            //DB更新用
+            //            deviceBound serialDeviceBoundRow = serialRow.deviceBound.Where(d => d.uuid == deviceBoundRow.uuid1 && d.uuid2 == deviceBoundRow.uuid2).FirstOrDefault();
+            //            if (serialDeviceBoundRow.deviceId != deviceRow.device_id)
+            //            {
+            //                deviceBoundRich deviceBoundUpdRow = new deviceBoundRich();
+            //                deviceBoundUpdRow.serial = deviceRow.sn;
+            //                deviceBoundUpdRow.uuid = deviceBoundRow.uuid1;
+            //                deviceBoundUpdRow.uuid2 = deviceBoundRow.uuid2;
+            //                deviceBoundUpdRow.classId = deviceBoundRow.class_id;
+            //                deviceBoundUpdRow.deviceId = deviceRow.device_id;
+            //                serialDeviceUpdList.Add(deviceBoundUpdRow);
+            //            }
+            //        }
+            //        serialRow.deviceBound = deviceBoundArray;
+            //    }
+
+            //    //服務
+            //    if (json.RootElement.TryGetProperty("service", out JsonElement serviceJobj) && serviceJobj.ValueKind != JsonValueKind.Null)
+            //    {
+            //        //取得active的主週期、所有主週期歷史
+            //        List<ServiceMainPeriod> activeMainPeriod = new List<ServiceMainPeriod>();
+            //        List<ServiceMainPeriod> historyMainPeriod = new List<ServiceMainPeriod>();
+            //        //ServiceMainPeriod activeMainPeriod = new ServiceMainPeriod();
+            //        if (serviceJobj.TryGetProperty("mainperiod", out JsonElement mainperiodJobj))
+            //        {
+            //            foreach (var mainperiodRow in mainperiodJobj.EnumerateArray())
+            //            {
+            //                historyMainPeriod.Add(mainperiodRow.ToObject<ServiceMainPeriod>());
+            //                if (mainperiodRow.GetProperty("active").GetBoolean())
+            //                {
+            //                    activeMainPeriod.Add(mainperiodRow.ToObject<ServiceMainPeriod>());
+            //                }
+            //            }
+            //        }
+
+            //        //取得active主週期的副週期
+            //        List<ServicePeriod> activePeriodOfMain = new List<ServicePeriod>();
+            //        List<ServicePeriod> historyPeriodOfMain = new List<ServicePeriod>();
+            //        if (serviceJobj.TryGetProperty("period", out JsonElement periodJobj))
+            //        {
+            //            foreach (var periodRow in periodJobj.EnumerateArray())
+            //            {
+            //                historyPeriodOfMain.Add(periodRow.ToObject<ServicePeriod>());
+            //                foreach (ServiceMainPeriod mainPeriodRow in activeMainPeriod)
+            //                {
+            //                    if (periodRow.GetProperty("mainPeriodId").ToString() == mainPeriodRow.mainPeriodId)
+            //                    {
+            //                        activePeriodOfMain.Add(periodRow.ToObject<ServicePeriod>());
+            //                    }
+            //                }
+            //            }
+            //        }
+            //        //計算各產品時間區域
+            //        bool buySpaceFlg = false;
+            //        ////取得學校空間使用狀況
+            //        var blobClient = _azureStorage.GetBlobContainerClient(school_code.ToString());
+            //        long? docSize = await blobClient.GetBlobsSize("doc");
+            //        long? videoSize = await blobClient.GetBlobsSize("video");
+            //        long? imageSize = await blobClient.GetBlobsSize("image");
+            //        long? paperSize = await blobClient.GetBlobsSize("paper");
+            //        long? itemSize = await blobClient.GetBlobsSize("item");
+            //        long? otherSize = await blobClient.GetBlobsSize("other");
+            //        long? studentSize = await blobClient.GetBlobsSize("student");
+            //        long teacherSize = 0;
+            //        if (serviceJobj.TryGetProperty("product", out JsonElement serviceProductJobj))
+            //        {
+
+            //            foreach (var serviceProductRow in serviceProductJobj.EnumerateArray())
+            //            {
+            //                ServiceProductResult serviceProductResultRow = CalServiceProductAuth(activeMainPeriod, activePeriodOfMain, serviceProductRow.ToObject<ServiceProduct>());
+            //                if (!string.IsNullOrWhiteSpace(serviceProductResultRow.prodCode))
+            //                {
+            //                    switch (serviceProductResultRow.prodCode)
+            //                    {
+            //                        case "RYGVCPLY": //AClassOne買斷、週期
+            //                        case "AEGMCPLY":
+            //                            ServiceProductAclassoneResult serviceProductAclassoneResult = new ServiceProductAclassoneResult();
+            //                            serviceProductAclassoneResult.prodCode = serviceProductResultRow.prodCode;
+            //                            serviceProductAclassoneResult.noperiod = serviceProductResultRow.noperiod;
+            //                            serviceProductAclassoneResult.serviceType = serviceProductResultRow.serviceType;
+            //                            serviceProductAclassoneResult.startDate = serviceProductResultRow.startDate;
+            //                            serviceProductAclassoneResult.endDate = serviceProductResultRow.endDate;
+            //                            serviceProductAclassoneResult.avaliable = serviceProductResultRow.avaliable;
+            //                            serviceProductAclassoneResult.staUsed = 0;
+            //                            serviceProductAclassoneResult.dynUsed = 0;
+            //                            if (json.RootElement.TryGetProperty("aclassone", out JsonElement aclassoneJobj) && aclassoneJobj.ValueKind != JsonValueKind.Null)
+            //                            {
+            //                                int total = (aclassoneJobj.TryGetProperty("total", out JsonElement totalJobj)) ? totalJobj.GetInt32() : 0;
+            //                                serviceProductAclassoneResult.staUsed = (aclassoneJobj.TryGetProperty("used", out JsonElement usedJobj)) ? usedJobj.GetInt32() : 0; //固定分配數
+            //                                List<string> dyncIdList = GetSchoolDynamicAclassOneIDList(school_code.GetString()); //動態使用ID
+            //                                serviceProductAclassoneResult.dynUsed = dyncIdList.Count;
+            //                            }
+            //                            service.Add(serviceProductAclassoneResult);
+            //                            break;
+            //                        case "IPALYEIY": //智慧教學服務空間
+            //                            ////取得目前使用狀況
+            //                            //取得教師分配空間
+            //                            var query = $"SELECT SUM(c.size) as size FROM c";
+            //                            await foreach (var item in clientContainer.GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school_code}") }))
+            //                            {
+            //                                var jsonts = await JsonDocument.ParseAsync(item.ContentStream);
+            //                                foreach (var obj in jsonts.RootElement.GetProperty("Documents").EnumerateArray())
+            //                                {
+            //                                    teacherSize = obj.GetProperty("size").GetInt64() * 1073741824;//G換算成bytes
+            //                                }
+            //                            }
+            //                            //欄位取得
+            //                            dynamic serviceSpaceProductInfo = new ExpandoObject();
+            //                            serviceSpaceProductInfo.prodCode = serviceProductResultRow.prodCode;
+            //                            serviceSpaceProductInfo.noperiod = serviceProductResultRow.noperiod;
+            //                            serviceSpaceProductInfo.serviceType = serviceProductResultRow.serviceType;
+            //                            serviceSpaceProductInfo.startDate = serviceProductResultRow.startDate;
+            //                            serviceSpaceProductInfo.endDate = serviceProductResultRow.endDate;
+            //                            serviceSpaceProductInfo.avaliable = (long)(serviceProductResultRow.avaliable + this.baseSpaceSize) * 1073741824; //G換算成bytes
+            //                            serviceSpaceProductInfo.doc = docSize;
+            //                            serviceSpaceProductInfo.video = videoSize;
+            //                            serviceSpaceProductInfo.image = imageSize;
+            //                            serviceSpaceProductInfo.paper = paperSize;
+            //                            serviceSpaceProductInfo.item = itemSize;
+            //                            serviceSpaceProductInfo.other = otherSize;
+            //                            serviceSpaceProductInfo.student = studentSize;
+            //                            serviceSpaceProductInfo.teacher = teacherSize;
+            //                            serviceSpaceProductInfo.history = CalServiceProductOrderHistory(historyMainPeriod, historyPeriodOfMain, serviceProductRow.ToObject<ServiceProduct>()); ////購買紀錄
+            //                            service.Add(serviceSpaceProductInfo);
+            //                            buySpaceFlg = true;
+            //                            break;
+            //                        default:
+            //                            service.Add(serviceProductResultRow);
+            //                            break;
+            //                    }
+            //                }
+            //            }
+            //        }
+            //        //學校保底空間追加
+            //        if (!buySpaceFlg) //未購買任何空間
+            //        {
+            //            dynamic serviceSpaceProductInfo = new ExpandoObject();
+            //            serviceSpaceProductInfo.prodCode = "IPALYEIY";
+            //            serviceSpaceProductInfo.noperiod = false;
+            //            serviceSpaceProductInfo.serviceType = "space";
+            //            serviceSpaceProductInfo.startDate = 0;
+            //            serviceSpaceProductInfo.endDate = 0;
+            //            serviceSpaceProductInfo.avaliable = this.baseSpaceSize * 1073741824; //1G換算成bytes
+            //            serviceSpaceProductInfo.doc = docSize;
+            //            serviceSpaceProductInfo.video = videoSize;
+            //            serviceSpaceProductInfo.image = imageSize;
+            //            serviceSpaceProductInfo.paper = paperSize;
+            //            serviceSpaceProductInfo.item = itemSize;
+            //            serviceSpaceProductInfo.other = otherSize;
+            //            serviceSpaceProductInfo.student = studentSize;
+            //            serviceSpaceProductInfo.teacher = teacherSize;
+            //            serviceSpaceProductInfo.history = null;
+            //            service.Add(serviceSpaceProductInfo);
+            //        }
+            //    }
+            //}
+
 
-            return Ok(new { serial, service, hard });
         }
 
         /// <summary>
@@ -608,7 +822,7 @@ namespace TEAMModelOS.Controllers
         }
 
         /// <summary>
-        /// 計算各產品的購買歷史紀錄
+        /// 計算各產品的購買歷史紀錄 [舊制,不使用]
         /// </summary>
         /// <param name="mainPeriodList">所有的主周期</param>
         /// <param name="periodList">所有附屬周期</param>