Browse Source

Merge branch 'develop' into ZJ/develop-20220831

zj 2 năm trước cách đây
mục cha
commit
f515547bb9

+ 49 - 9
TEAMModelBI/ClientApp/src/view/areaServe/areamanage.vue

@@ -319,7 +319,7 @@
                     </p>
                   <div class="examine-tables">
                     <div class="stagebox-table" >
-                  <el-table :data="adminSchoold.data" style="width: 100%" max-height="50vh" height="50vh" v-loading="adminSchoold.loading" element-loading-text="数据加载中...">
+                  <el-table :data="adminSchoold.data" style="width: 100%" max-height="50vh" height="50vh" v-loading="adminSchoold.loading" element-loading-text="数据加载中..." empty-text="暂无数据">
                     <el-table-column :label="$t(`areaManages.operational.areaAddSchool.tables.badge`)" align="center">
                       <template #default="scope">
                         <el-image :src="scope.row.picture" fit="fill"></el-image>
@@ -337,7 +337,7 @@
                         <el-input v-model="schoolSearch" size="small" placeholder="搜索学校名称/简码" clearable />
                       </template>
                       <template #default="scope">
-                        <el-button type="danger" size="small">移除对该校管理</el-button>
+                        <el-button type="danger" size="small" @click="removeSchool(scope.row)">移除对该校管理</el-button>
                       </template>
                     </el-table-column>
                   </el-table>
@@ -459,7 +459,7 @@
             <div class="right-back"><el-button size="small" type="primary" @click="stageShow.definedShow=false,stageShow.width='20%'"> <el-icon><Back /></el-icon>返回</el-button></div>
           </div>
           <div class="stagebox-table">
-            <el-table :data="stageShow.definedData" style="width: 100%" max-height="50vh" height="40vh" @selection-change="selectChange">
+            <el-table :data="stageShow.definedData" style="width: 100%" max-height="50vh" height="40vh" @selection-change="selectChange" empty-text="暂无数据">
                     <el-table-column type="selection" width="55" />
                     <el-table-column :label="$t(`areaManages.operational.areaAddSchool.tables.badge`)" align="center">
                       <template #default="scope">
@@ -586,6 +586,7 @@ export default {
       loading:false,
       allLoading:false,
       customLoading:false,
+      nowid:'',
     })
     let schoolSearch=ref('')
     let timer=ref('')
@@ -906,7 +907,7 @@ export default {
         .areaAddadmins(data)
         .then((res) => {
           console.log(res, '添加学区管理员返回')
-          res.state === 200 ? (ElMessage.success('操作成功'), getAreasadmin()) : ''
+          res.state === 200 ? (ElMessage.success('操作成功'), stageShow.value.state=false,getAreasadmin()) : ''
         })
         .catch((error) => {
           ElMessage.error('添加学区管理员失败')
@@ -922,13 +923,24 @@ export default {
       let data=state ==='all' ? ({tmdId: searchData.value.id, tmdName: searchData.value.name, tmdPic: searchData.value.picture, areaId: currentlySelect.value.id, areaName: currentlySelect.value.name,isSc:'yesm',scInfos:tableDatas.value})
       :({tmdId: searchData.value.id, tmdName: searchData.value.name, tmdPic: searchData.value.picture, areaId: currentlySelect.value.id, areaName: currentlySelect.value.name,isSc:'yesm',scInfos:concernSchoolArr.value})
       proxy.$api.areaAddadmins(data).then((res)=>{
-        res.state === 200 ? (ElMessage.success('操作成功'), getAreasadmin()) : ''
+        // res.state === 200 ? (ElMessage.success('操作成功'), getAreasadmin()) : ''
+        if(res.state ===200 || res.state===201){
+          if(res.existsArea !== null){
+            ElMessage.warning('该管理员已是本学区管理员,请勿重复添加')
+          }else if(res.existsSc.length !==0){
+            ElMessage.success('操作成功')
+            stageShow.value.state=false
+            getAreasadmin()
+          }else if(res.errorSc.length !==0){
+            ElMessage.error('全部或部分设置学校管理员操作失败')
+          }
+        }
       }).catch((error)=>{
         ElMessage.error('批量添加学区管理员失败')
       })
       setTimeout(() => {
-    loading.close()
-  }, 1000)
+        loading.close()
+      }, 1000)
       // state === 'all' ? adminSchoold.value.allLoading=false:adminSchoold.value.customLoading=false
     }
     function removeadmin (value) {
@@ -959,6 +971,32 @@ export default {
           })
       })
     }
+    //移除管理员对学校的管理
+    function removeSchool(value){
+      console.log(value)
+      ElMessageBox.confirm(`请问您确定从当前管理员列表中移除  ${value.name}  吗?`, '移除管理学校', {
+        confirmButtonText: proxy.$t(`commonMsg.confirm`),
+        cancelButtonText: proxy.$t(`commonMsg.closes`),
+        type: 'error',
+        center: true,
+      }).then(() => {
+        let data = { tmdId:adminSchoold.value.nowid, scId:value.id }
+        proxy.$api
+          .deleteSchooladmin(data)
+          .then((res) => {
+            res.state === 200 ?
+              (ElMessage.success('操作成功'), admintheSchool(adminSchoold.value.nowid,adminIndex.value)) :
+              res.state === 403 ?
+                ElMessage.error('管理员至少存在一位,无法移除当前人员') :
+                res.state === 1 ?
+                  ElMessage.error('无法删除自己,操作失败') :
+                  ''
+          })
+          .catch((error) => {
+            ElMessage.error('删除失败')
+          })
+      })
+    }
     //自定义加入学区管理员
     function defined(){
       stageShow.value.definedShow=true
@@ -986,9 +1024,10 @@ export default {
     //学区内某个管理员关联的学校
     function admintheSchool(id,index){
       adminSchoold.value.loading=true
+      adminSchoold.value.nowid=id
       adminOrsearch.value='Vdetails'
       adminIndex.value=index
-      let data={tmdId:id}
+      let data={tmdId:id,areaId:currentlySelect.value.id}
       proxy.$api.adminRelevanceschool(data).then((res)=>{
         console.log(res,'管理返回')
         res.state === 200 ? adminSchoold.value.data=res.mScInfos:''
@@ -1075,7 +1114,8 @@ export default {
       adminIndex,
       admintheSchool,
       adminSchoold,
-      batchAddadmin
+      batchAddadmin,
+      removeSchool
     }
   },
 }

+ 1 - 1
TEAMModelBI/ClientApp/src/view/common/footer.vue

@@ -9,7 +9,7 @@
       </el-icon>
       数据中心位置 中国
     </span>
-    <span>V1.2208.17.1</span>
+    <span>V1.2208.31.1</span>
   </div>
 </template>
 <script>

+ 14 - 13
TEAMModelOS.SDK/DI/CoreAPI/CoreAPIHttpService.cs

@@ -49,23 +49,23 @@ namespace TEAMModelOS.SDK
     }
     public class CoreAPIHttpService
     {
-        private readonly IWebHostEnvironment _environment;
+        //private readonly IWebHostEnvironment _environment;
         public bool check=true;
         private SnowflakeId _snowflakeId;
         private readonly HttpClient _httpClient;
         public readonly IOptionsMonitor<CoreAPIHttpServiceOptions> options;
-        private readonly IConfiguration _configuration;
-        private readonly DI.DingDing _dingDing;
-        public readonly Option _option;
-        public CoreAPIHttpService(IOptionsSnapshot<Option> option, DingDing dingDing,IConfiguration configuration,HttpClient httpClient, IOptionsMonitor<CoreAPIHttpServiceOptions> optionsMonitor, IWebHostEnvironment environment,SnowflakeId snowflakeId)
+        //private readonly IConfiguration _configuration;
+       // private readonly DI.DingDing _dingDing;
+        //public readonly Option _option;
+        public CoreAPIHttpService(HttpClient httpClient, IOptionsMonitor<CoreAPIHttpServiceOptions> optionsMonitor,  SnowflakeId snowflakeId)
         {
             _httpClient = httpClient;
             options = optionsMonitor;
-            _environment = environment;
+            //_environment = environment;
             _snowflakeId= snowflakeId;
-            _option = option?.Value;
-            _configuration = configuration;
-            _dingDing = dingDing;
+            //_option = option?.Value;
+            //_configuration = configuration;
+            //_dingDing = dingDing;
 
         }
         /*
@@ -108,7 +108,8 @@ namespace TEAMModelOS.SDK
         /// <param name="_configuration"></param>
         /// <param name="_dingDing"></param>
         /// <returns></returns>
-        public   void PushNotify(List<IdNameCode> toTeachers ,  string notifyCode,string notifyType,Dictionary<string, object> replaceData) {
+        public   void PushNotify(List<IdNameCode> toTeachers ,  string notifyCode,string notifyType,Dictionary<string, object> replaceData, 
+            string location, IConfiguration _configuration, DI.DingDing _dingDing,string rootPath) {
             /*
              * IES5_Management  shift-assist_school  DelBeforeCopyAbility-mark_start  copyAbility-mark_finish  copyAbility-mark_start 
              *                  transfer-admin_school invite-join_school invite_school  request_school request-join_school remove_school  scan-join_school
@@ -126,17 +127,17 @@ namespace TEAMModelOS.SDK
                 "data":""action":{"type":"click\link","tokenbindtype":1,"url":"http://xxxx"}"
             }
             */
-            string lang = _option.Location.Contains("China") ? "zh-cn" : "en-us";
+            string lang = location.Contains("China") ? "zh-cn" : "en-us";
             toTeachers.FindAll(x => string.IsNullOrWhiteSpace(x.code)||(!x.code.Equals("zh-cn")&& !x.code.Equals("zh-tw")&& !x.code.Equals("en-us"))).ForEach(x => { x.code = lang; });
             var groups = toTeachers.GroupBy(x => x.code).Select(x => new { x.Key, list = x.ToList() });
             var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
             var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
             var url = _configuration.GetValue<string>("HaBookAuth:CoreAPI");
-            var token = CoreTokenExtensions.CreateAccessToken(clientID, clientSecret,_option.Location).Result;
+            var token = CoreTokenExtensions.CreateAccessToken(clientID, clientSecret,location).Result;
             _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {token.AccessToken}");
             foreach (var group in groups)
             {
-                string path = $"{_environment.ContentRootPath}/Lang/{group.Key}.json";
+                string path = $"{rootPath}/Lang/{group.Key}.json";
                 var sampleJson = File.ReadAllBytes(path).AsSpan();
                 Utf8JsonReader reader = new Utf8JsonReader(sampleJson);
                 if (JsonDocument.TryParseValue(ref reader, out JsonDocument jsonDoc) && jsonDoc.RootElement.TryGetProperty(notifyCode, out JsonElement json )) {

+ 1 - 1
TEAMModelOS/ClientApp/public/lang/en-US.js

@@ -1426,7 +1426,7 @@ const LANG_EN_US = {
         index: {
             item: 'Questions',
             paper: 'Exam Files',
-            addExercise: 'Create Question',
+            addExercise: 'Add Question',
             openAll: 'Unfold All',
             collapseAll: 'Fold All',
             autoCreate: 'SMART Design',

+ 7 - 7
TEAMModelOS/ClientApp/public/lang/zh-CN.js

@@ -1425,7 +1425,7 @@ const LANG_ZH_CN = {
         index: {
             item: '试题',
             paper: '试卷',
-            addExercise: '新建习题',
+            addExercise: '添加题目',
             openAll: '全部展开',
             collapseAll: '全部折叠',
             autoCreate: '智能组卷',
@@ -2586,9 +2586,9 @@ const LANG_ZH_CN = {
             sheetErr: '答题卡处理失败',
             noAuth: '未授权',
             noSchool: '未加入学校',
-            sort1:'重新挑选试卷',
-            sort2:'阅卷评测暂不支持题号排序的试卷,请重新挑选试卷',
-            sort3:'阅卷评测不能挑选题号排序的试卷',
+            sort1: '重新挑选试卷',
+            sort2: '阅卷评测暂不支持题号排序的试卷,请重新挑选试卷',
+            sort3: '阅卷评测不能挑选题号排序的试卷',
         },
         // ManualPaper.vue
         manual: {
@@ -6436,9 +6436,9 @@ const LANG_ZH_CN = {
             signOk: '签到成功',
             unStart: '未开始签到',
             school: '学校:',
-            upd1:'修改封面',
-            upd2:'修改成功',
-            upd3:'修改失败',
+            upd1: '修改封面',
+            upd2: '修改成功',
+            upd3: '修改失败',
         }
     },
     //研修

+ 1 - 1
TEAMModelOS/ClientApp/public/lang/zh-TW.js

@@ -1426,7 +1426,7 @@ const LANG_ZH_TW = {
         index: {
             item: '試題',
             paper: '試卷',
-            addExercise: '新增試題',
+            addExercise: '添加題目',
             openAll: '全部展開',
             collapseAll: '全部折疊',
             autoCreate: '智慧組卷',

+ 15 - 0
TEAMModelOS/ClientApp/src/utils/evTools.js

@@ -195,6 +195,21 @@ export default {
 		})
 	},
 
+	/* 根据醍摩豆ID获取对应BLOB个人容器授权信息 */
+	getBlobPrivateSasObj(tmdId) {
+		return new Promise((r, j) => {
+			$api.blob.blobSasR({
+				name: tmdId,
+				role: 'teacher'
+			}).then(res => {
+				if (!res.error) {
+					res.sas = '?' + res.sas
+					r(res)
+				}
+			})
+		})
+	},
+
 	/* 根据醍摩豆ID获取对应BLOB个人容器授权信息 */
 	getBlobSchoolSas(schoolCode) {
 		return new Promise((r, j) => {

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

@@ -1,8 +1,21 @@
 <template>
   <div class="paper-item-picker-container">
     <div class="paper-list">
-      <p style="font-size:16px;margin-left:20px;" v-if="paperList.length">当前已挑选 <span style="font-weight:bold;color:#42a676">{{ checkList.length }}</span> 题</p>
-      <p style="font-size:16px;margin-left:20px;" v-if="!paperList.length">当前无试卷可选择!</p>
+      <div style="display: flex;align-items: center;margin-bottom: 10px;font-size:14px !important">
+        <div class="action-tool" style="display: flex;align-items: center;">
+          <span class="action-title" style="margin-left:20px;width: 80px;">{{ $t('evaluation.tag') }}:</span>
+          <Select v-model="selectTags" multiple style="min-width:100px" @on-change="onTagChange">
+            <Option v-for="item in tags" :value="item" :key="item">{{ item }}</Option>
+          </Select>
+        </div>
+        <div class="action-tool" style="display: flex;margin-left:20px;">
+          <Input v-special-char suffix="ios-search" v-model="searchVal" clearable :placeholder="$t('evaluation.paperList.searchPaper')" style="width: 300px" @on-click="onCloseSearch" @on-change="onSearchChange" />
+        </div>
+        <div>
+          <p style="margin-left:20px;" v-if="paperList.length">当前已挑选 <span style="font-weight:bold;color:#42a676">{{ checkList.length }}</span> 题</p>
+          <p style="margin-left:20px;" v-if="!paperList.length">当前无试卷可选择!</p>
+        </div>
+      </div>
       <Collapse simple v-if="paperList.length" accordion @on-change="onPaperClick">
         <Panel v-for="(paper,index) in paperList" color="primary" :name="paper.id">
           <span style="display:inline-flex;align-items: center">
@@ -50,7 +63,11 @@ export default {
   },
   data() {
     return {
+      searchVal: '',
+      tags: [],
       paperList: [],
+      selectTags: [],
+      originList: [],
       questionList: [],
       checkList: [],
       originQuestionList: [],
@@ -61,6 +78,20 @@ export default {
     this.findPaper()
   },
   methods: {
+    /* 搜索词汇发生变化 */
+    onSearchChange() {
+      let val = this.searchVal
+      this.paperList = this.originList.filter(i => i.name.indexOf(val) > -1)
+    },
+    /* 关闭搜索 */
+    onCloseSearch() {
+      this.searchVal = ''
+      this.paperList = JSON.parse(JSON.stringify(this.originList))
+    },
+    /* 标签选择发生变化 */
+    onTagChange(val) {
+      this.paperList = val.length ? this.originList.filter(i => val.find(j => i.tags.includes(j))) : this.originList
+    },
     onQuestionClick(item, index) {
       let findIndex = this.checkList.findIndex(i => i.id === item.id)
       if (findIndex > -1) {
@@ -81,6 +112,10 @@ export default {
         'subjectId': this.isSchool ? [this.subjectCode] : []
       }).then(res => {
         this.paperList = res.papers
+        this.originList = this._.cloneDeep(res.papers)
+        if (res.papers.length > 0) {
+          this.tags = [...new Set(res.papers.map(i => i.tags).flat(1))]
+        }
       })
     },
     async onPaperClick(paperId) {
@@ -108,6 +143,7 @@ export default {
 
 <style lang="less">
 .paper-item-picker-container {
+  min-height: 400px;
   .ivu-collapse {
     border: none;
   }

+ 12 - 5
TEAMModelOS/ClientApp/src/view/evaluation/index/TestPaper.vue

@@ -55,18 +55,18 @@
     </div>
 
     <!-- 新建试题 -->
-    <Modal v-model="addNewModal" :mask-closable="false" :title="$t('evaluation.index.addExercise')" width="1000px" class="related-point-modal edit-exercise-modal">
+    <Modal v-model="addNewModal" @on-visible-change="onAddNewModalChange" :mask-closable="false" :title="$t('evaluation.index.addExercise')" width="1000px" class="related-point-modal edit-exercise-modal">
       <Tabs value="name1" name="newExerciseTab" @on-click="onTabChange" :animated="false">
         <TabPane :label="$t('evaluation.autoCreate')" name="name1" tab="newExerciseTab">
           <BaseCreateChild @addFinish="onAddNewFinish" ref="newEdit" v-if="addNewModal" :curPeriodIndex="paperInfo.paperPeriod" :curSubjectIndex="paperInfo.paperSubject">
           </BaseCreateChild>
         </TabPane>
-        <TabPane :label="$t('evaluation.quickCreate')" name="name2" tab="newExerciseTab" v-if="isDevEnv">
+        <!-- <TabPane :label="$t('evaluation.quickCreate')" name="name2" tab="newExerciseTab" v-if="isDevEnv">
           <BasePasteTool v-if="addNewModal" @addFinish="onAddNewFinish"></BasePasteTool>
-        </TabPane>
-        <!-- <TabPane :label="`从题库挑选`" name="name3" tab="newExerciseTab">
-          <ManualCreate v-if="curModalTab === 'name3'" ref="bankPicker" :subjectCode="subjectCode" :periodCode="periodCode" :gradeCode="gradeCode"></ManualCreate>
         </TabPane> -->
+        <TabPane :label="`从题库挑选`" name="name3" tab="newExerciseTab">
+          <ManualCreate ref="bankPicker" :subjectCode="subjectCode" :periodCode="periodCode" :gradeCode="gradeCode"></ManualCreate>
+        </TabPane>
         <TabPane :label="`从试卷挑选`" name="name4" tab="newExerciseTab">
           <BasePaperItemPicker v-if="curModalTab === 'name4'" ref='paperPicker' :subjectCode="subjectCode" :periodCode="periodCode" :gradeCode="gradeCode"></BasePaperItemPicker>
         </TabPane>
@@ -223,6 +223,13 @@ export default {
       // this.paperInfo.item = this._.cloneDeep(val.item)
 
     },
+    onAddNewModalChange(val) {
+      if (val) {
+        this.$refs.bankPicker && (this.$refs.bankPicker.shoppingQuestionList = [])
+        this.$refs.bankPicker && (this.$refs.bankPicker.$refs.exList.selectList = [])
+        this.$refs.paperPicker && (this.$refs.paperPicker.checkList = [])
+      }
+    },
     /* 退出预览 */
     exitPreview() {
       this.$emit('exitPreview')

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

@@ -498,12 +498,14 @@ export default {
     },
     gradeCode: {
       handler(n, o) {
+        console.error(n)
         if (n) {
           this.manualFilter.gradeIds = n.length ? n.map(i => i + '') : []
           this.condName.gradeName = n.length ? n.map(i => this.gradeList[i]).join(',') : this.$t('evaluation.filter.allGrades')
           this.queryQuestionByPage('grade')
         }
-      }
+      },
+      deep: true,
     },
   }
 }

+ 11 - 5
TEAMModelOS/ClientApp/src/view/syllabus/Syllabus.vue

@@ -1313,6 +1313,12 @@ export default {
                 `syllabus/${node.newNodeId}/${file.id}/`,
                 `syllabus/${node.nodeId}/${file.id}`, file,
                 privateBlobTool))
+            } else if (copyFile.type === 'res' && this.getSuffix(copyFile.title) === 'htex') {
+              let htexName = copyFile.title.replace('.htex', '').replace('.HTEX', '')
+              promiseArr.push(this.copySameFolderToBlob(
+                `syllabus/${node.newNodeId}/${htexName}/`,
+                `syllabus/${node.nodeId}/${htexName}`, file,
+                privateBlobTool))
             } else if (copyFile.type !== 'link') {
               // 单个文件进行blob复制
               promiseArr.push(this.copyFileToBlob(file, node.newNodeId, node.nodeId))
@@ -2156,19 +2162,19 @@ export default {
     },
     /* 下载资源 */
     async onDownload(item, index) {
-      let sasObj = item.scope === 'school' ? await this.$tools.getSchoolSas() : await this.$evTools.getBlobPrivateSas(item.cntr)
+      let sasObj = item.scope === 'school' ? await this.$tools.getSchoolSas() : await this.$evTools.getBlobPrivateSasObj(item.cntr)
       if (this.getSuffix(item.title).toLowerCase() === 'htex') {
-        let sasString = item.scope === 'school' ? sasObj.sas : sasObj
-        this.containerClient.listBlob({
+        let containerClient = new BlobTool(sasObj.url, sasObj.name, sasObj.sas, this.curScope)
+        containerClient.listBlob({
           prefix: item.link.replace('.HTEX', '').replace('.htex', '').substr(1),
         }, false).then(
           res => {
-            let urls = res.blobList.map(i => i.url + sasString)
+            let urls = res.blobList.map(i => i.url + sasObj.sas)
             this.$tools.doBatchDownloadZip(urls, item.title, true)
           }
         )
       } else {
-        let fullLink = this.$evTools.getBlobHost() + '/' + item.cntr + item.link + (item.scope === 'school' ? sasObj.sas : sasObj)
+        let fullLink = this.$evTools.getBlobHost() + '/' + item.cntr + item.link + sasObj.sas
         this.$tools.doDownloadByUrl(fullLink, item.title)
       }
     },

+ 14 - 0
TEAMModelOS/Controllers/Client/HiTAControlller.cs

@@ -20,6 +20,7 @@ using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.DI.CoreAPI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Dtos;
 using TEAMModelOS.SDK.Models.Service;
 using TEAMModelOS.SDK.Services;
 using static TEAMModelOS.SDK.Services.BlobService;
@@ -40,7 +41,9 @@ namespace TEAMModelOS.Controllers.Client
         private readonly NotificationService _notificationService;
         private readonly IPSearcher _searcher;
         private readonly HttpTrigger _httpTrigger;
+        private readonly CoreAPIHttpService _coreAPIHttpService;
         public HiTAControlller(
+            CoreAPIHttpService coreAPIHttpService,
             AzureStorageFactory azureStorage,
             AzureRedisFactory azureRedis,
             AzureCosmosFactory azureCosmos,
@@ -58,6 +61,7 @@ namespace TEAMModelOS.Controllers.Client
             _notificationService = notificationService;
             _searcher = searcher;
             _httpTrigger = httpTrigger;
+            _coreAPIHttpService = coreAPIHttpService;
         }
 
         public class HiTAJoinSchool
@@ -212,6 +216,16 @@ namespace TEAMModelOS.Controllers.Client
             var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
             var location = _option.Location;
             var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
+
+            string tsql = $"select c.id, c.name ,c.lang as code from c where c.id in ({string.Join(",", ids.Select(x => $"'{x}'"))})";
+            List<IdNameCode> idNameCodes = new List<IdNameCode>();
+            await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
+                .GetItemQueryIterator<IdNameCode>(queryText: tsql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
+            {
+                idNameCodes.Add(item);
+            }
+            _coreAPIHttpService.PushNotify(idNameCodes, $"{bizcode}_school", Constant.NotifyType_IES5_Management,
+                      new Dictionary<string, object> { { "tmdname", name }, { "schooName", schoolInfo.name } }, _option.Location, _configuration, _dingDing);
             return Ok(new { schoolTeacher.roles, schoolTeacher.status, school = $"{school}", schoolInfo.name, schoolInfo.picture });
         }
 

+ 19 - 0
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -29,6 +29,7 @@ using HTEXLib.COMM.Helpers;
 using Microsoft.AspNetCore.Authorization;
 using System.Net.Http;
 using TEAMModelOS.SDK.DI.CoreAPI;
+using TEAMModelOS.SDK.Models.Dtos;
 
 namespace TEAMModelOS.Controllers
 {
@@ -2895,6 +2896,15 @@ namespace TEAMModelOS.Controllers
                                         var location = _option.Location;
                                         await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
                                         await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync(scoring, scoring.id, new PartitionKey(scoring.code));
+                                        string sql = $"select c.id, c.name ,c.lang as code from c where c.id in ({string.Join(",", ids.Select(x => $"'{x}'"))})";
+                                        List<IdNameCode> idNameCodes = new List<IdNameCode>();
+                                        await foreach (var idNameCode in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
+                                            .GetItemQueryIterator<IdNameCode>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
+                                        {
+                                            idNameCodes.Add(idNameCode);
+                                        }
+                                        _coreAPIHttpService.PushNotify(idNameCodes, $"{bizcode}_school", Constant.NotifyType_IES5_Task,
+                                                  new Dictionary<string, object> { { "tmdname", name }, { "schooName", schname } }, _option.Location, _configuration, _dingDing);
                                         return Ok(new { msg = "需要仲裁", code = 2 });
                                     }
                                     if (item.scores.Count > 0)
@@ -3051,6 +3061,15 @@ namespace TEAMModelOS.Controllers
                 var location = _option.Location;
                 await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
 
+                string sql = $"select c.id, c.name ,c.lang as code from c where c.id in ({string.Join(",", ids.Select(x => $"'{x}'"))})";
+                List<IdNameCode> idNameCodes = new List<IdNameCode>();
+                await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
+                    .GetItemQueryIterator<IdNameCode>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
+                {
+                    idNameCodes.Add(item);
+                }
+                _coreAPIHttpService.PushNotify(idNameCodes, $"{bizcode}_school", Constant.NotifyType_IES5_Task,
+                          new Dictionary<string, object> { { "tmdname", name }, { "schooName", schname } }, _option.Location, _configuration, _dingDing);
                 /* scoring.type = 2;
                  scoring.err = err.GetString();*/
             }

+ 4 - 0
TEAMModelOS/Controllers/Common/HomeworkController.cs

@@ -803,6 +803,10 @@ namespace TEAMModelOS.Controllers.Learn
                                     var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
                                     var location = _option.Location;
                                     var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
+                                  Teacher teacherData= await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>(homework.creatorId, new PartitionKey("Base"));
+                                    _coreAPIHttpService.PushNotify(new List<IdNameCode> { 
+                                        new IdNameCode { id = teacherData.id,name=teacherData.name,code=teacherData.lang} }, "submitanswer_homework", Constant.NotifyType_IES5_Course,
+                               new Dictionary<string, object> { { "tmdname", name }, { "homeworkName", homework.name } }, _option.Location, _configuration, _dingDing,"");
                                 }
                                 //TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO 写入方便教师查看的作答记录
                                 try

+ 14 - 2
TEAMModelOS/Controllers/School/CorrectController.cs

@@ -27,6 +27,7 @@ using TEAMModelOS.SDK.Models.Service;
 using Microsoft.Extensions.Configuration;
 using HTEXLib.COMM.Helpers;
 using TEAMModelOS.SDK.DI.CoreAPI;
+using TEAMModelOS.SDK.Models.Dtos;
 
 namespace TEAMModelOS.Controllers
 {
@@ -46,8 +47,8 @@ namespace TEAMModelOS.Controllers
         private readonly AzureStorageFactory _azureStorage;
         private readonly IConfiguration _configuration;
         private readonly NotificationService _notificationService;
-
-        public CorrectController(AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, IConfiguration configuration, NotificationService notificationService,
+        private readonly CoreAPIHttpService _coreAPIHttpService;
+        public CorrectController(CoreAPIHttpService coreAPIHttpService,AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, IConfiguration configuration, NotificationService notificationService,
             AzureRedisFactory azureRedis, AzureStorageFactory azureStorage)
         {
             _azureCosmos = azureCosmos;
@@ -59,6 +60,7 @@ namespace TEAMModelOS.Controllers
             _azureStorage = azureStorage;
             _configuration = configuration;
             _notificationService = notificationService;
+            _coreAPIHttpService = coreAPIHttpService;
         }
 
         ///<summary>
@@ -245,6 +247,16 @@ namespace TEAMModelOS.Controllers
                 var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
                 var location = _option.Location;
                 await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
+
+                string sql = $"select c.id, c.name ,c.lang as code from c where c.id in ({string.Join(",", ids.Select(x => $"'{x}'"))})";
+                List<IdNameCode> idNameCodes = new List<IdNameCode>();
+                await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
+                    .GetItemQueryIterator<IdNameCode>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
+                {
+                    idNameCodes.Add(item);
+                }
+                _coreAPIHttpService.PushNotify(idNameCodes, $"{bizcode}_school", Constant.NotifyType_IES5_Task,
+                                 new Dictionary<string, object> { { "tmdname", name }, { "schooName", schname } }, _option.Location, _configuration, _dingDing,"");
                 return Ok(new { vote = request });
             }
             catch (Exception e)

+ 13 - 5
TEAMModelOS/Controllers/School/SchoolController.cs

@@ -27,6 +27,7 @@ using System.Net.Http.Json;
 using HTEXLib.COMM.Helpers;
 using System.IdentityModel.Tokens.Jwt;
 using TEAMModelOS.SDK.DI.CoreAPI;
+using Azure.Storage.Blobs.Models;
 
 namespace TEAMModelOS.Controllers
 {
@@ -1573,7 +1574,7 @@ namespace TEAMModelOS.Controllers
                         }
 
                     }
-                    List<string> inviteids = new List<string>();
+                    List<IdNameCode> inviteids = new List<IdNameCode>();
                     School schoolBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>($"{_schoolId}", new PartitionKey("Base"));
                     if (coreUsers.Any())
                     {
@@ -1667,12 +1668,13 @@ namespace TEAMModelOS.Controllers
                                         pk = "Teacher",
                                         code = $"Teacher-{_schoolId}"
                                     };
-                                    inviteids.Add(t.id);
+                                  
                                     await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).CreateItemAsync(teacher, new PartitionKey(teacher.code));
                                     Azure.Response responseTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(t.id, new PartitionKey("Base"));
                                     if (responseTeacher.Status == 200)
                                     {
                                         Teacher teacherBase = JsonDocument.Parse(responseTeacher.Content).RootElement.Deserialize<Teacher>();
+                                        inviteids.Add( new IdNameCode { id= teacherBase.id,name= teacherBase.name,code= teacherBase.lang});
                                         var school = teacherBase.schools?.Find(x => x.schoolId.Equals($"{_schoolId}"));
                                         if (teacherBase.schools.IsNotEmpty())
                                         {
@@ -1699,9 +1701,12 @@ namespace TEAMModelOS.Controllers
                                             code = "Base",
                                             pk = "Base",
                                             schools = new List<Teacher.TeacherSchool> {
-                                            new Teacher.TeacherSchool {schoolId= schoolBase.id,name= schoolBase.name,picture= schoolBase.picture, areaId= schoolBase.areaId,time=now,status= "invite" },
-                                        }
+                                                new Teacher.TeacherSchool {
+                                                    schoolId= schoolBase.id,
+                                                    name= schoolBase.name,picture= schoolBase.picture, areaId= schoolBase.areaId,time=now,status= "invite" },
+                                            }
                                         };
+                                        inviteids.Add(new IdNameCode { id = teacherBase.id, name = teacherBase.name, code = teacherBase.lang });
                                         await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).CreateItemAsync(teacherBase, new PartitionKey("Base"));
                                     }
 
@@ -1780,7 +1785,7 @@ namespace TEAMModelOS.Controllers
                             hubName = "hita",
                             type = "msg",
                             from = $"ies5:{_option.Location}:private",
-                            to = inviteids.Select(x => x).ToList(),
+                            to = inviteids.Select(x => x.id).ToList(),
                             label = $"{bizcode}_school",
                             body = new { location = _option.Location,
                                 biz = bizcode,
@@ -1798,6 +1803,9 @@ namespace TEAMModelOS.Controllers
                         var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
                         var location = _option.Location;
                         var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
+
+                        _coreAPIHttpService.PushNotify(inviteids, $"remove_school", Constant.NotifyType_IES5_Management,
+                                     new Dictionary<string, object> { { "tmdname", adminName }, { "schooName", schoolBase.name } }, _option.Location, _configuration, _dingDing,"");
                     }
                     break;
             }

+ 16 - 4
TEAMModelOS/Controllers/School/SchoolTeacherController.cs

@@ -22,6 +22,8 @@ using TEAMModelOS.Filter;
 using HTEXLib.COMM.Helpers;
 using Microsoft.AspNetCore.Authorization;
 using TEAMModelOS.SDK.DI.CoreAPI;
+using DocumentFormat.OpenXml.Wordprocessing;
+using static TEAMModelOS.Controllers.FixDataController;
 
 namespace TEAMModelOS.Controllers
 {
@@ -583,13 +585,13 @@ namespace TEAMModelOS.Controllers
             {
 
                 List<KeyValuePair<string, int>> keys = new List<KeyValuePair<string, int>>();
-                List<TmdInfo> ids = new List<TmdInfo>();
+                List<IdNameCode> ids = new List<IdNameCode>();
                 foreach (var obj in user_list.EnumerateArray())
                 {
                     obj.TryGetProperty("id", out JsonElement id);
                     obj.TryGetProperty("name", out JsonElement name);
                     obj.TryGetProperty("picture", out JsonElement picture);
-                    TmdInfo tmd = new TmdInfo { id = $"{id}", name = $"{name}" };
+                    IdNameCode tmd = new IdNameCode { id = $"{id}", name = $"{name}" };
                     ids.Add(tmd);
                     //老師個人資料
                     var tresponse = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemStreamAsync(id.ToString(), new PartitionKey("Base"));
@@ -597,7 +599,8 @@ namespace TEAMModelOS.Controllers
                     {
                         using var json = await JsonDocument.ParseAsync(tresponse.ContentStream);
                         Teacher teacher = json.ToObject<Teacher>();
-                        var school = teacher.schools.FirstOrDefault(x => x.schoolId.Equals(school_code.GetString(), StringComparison.OrdinalIgnoreCase));
+                        tmd.code = teacher.lang;
+                         var school = teacher.schools.FirstOrDefault(x => x.schoolId.Equals(school_code.GetString(), StringComparison.OrdinalIgnoreCase));
                         if (school != null)
                         {
                             school.time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
@@ -739,6 +742,9 @@ namespace TEAMModelOS.Controllers
                 var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
                 var location = _option.Location;
                 var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
+
+                _coreAPIHttpService.PushNotify(ids, $"{bizcode}_school", Constant.NotifyType_IES5_Management,
+                                 new Dictionary<string, object> { { "tmdname", tname }, { "schooName", schname } }, _option.Location, _configuration, _dingDing, "");
                 return Ok(new { exist = keys });
             }
             catch (Exception ex)
@@ -905,7 +911,10 @@ namespace TEAMModelOS.Controllers
                 var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
                 var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
                 var location = _option.Location;
-                var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
+                var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification); 
+
+                _coreAPIHttpService.PushNotify(new List<IdNameCode> { new IdNameCode { id = teacher.id, name=teacher.name, code= teacher.lang} }, $"{bizcode}_school", Constant.NotifyType_IES5_Management,
+                                 new Dictionary<string, object> { { "tmdname", tname }, { "schooName", schname } }, _option.Location, _configuration, _dingDing, "");
                 return Ok(new { });
             }
             catch (Exception ex)
@@ -1020,6 +1029,9 @@ namespace TEAMModelOS.Controllers
                     var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
                     var location = _option.Location;
                     var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
+
+                    _coreAPIHttpService.PushNotify(new List<IdNameCode> { new IdNameCode { id = teacher.id, name = teacher.name, code = teacher.lang } }, $"remove_school", Constant.NotifyType_IES5_Management,
+                                     new Dictionary<string, object> { { "tmdname", tname }, { "schooName", schname } }, _option.Location, _configuration, _dingDing, "");
                 }
                 return Ok(new { });
             }

+ 10 - 5
TEAMModelOS/Controllers/Teacher/InitController.cs

@@ -267,7 +267,7 @@ namespace TEAMModelOS.Controllers
                                 }
                                 Teacher targetTeacher = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>($"{_targetTecher}", new PartitionKey($"Base"));
                                 _coreAPIHttpService.PushNotify(new List<IdNameCode> { new IdNameCode { id= targetTeacher.id,name= targetTeacher.name,code=targetTeacher.lang} }, "transfer-admin_school", Constant.NotifyType_IES5_Management,
-                                    new Dictionary<string, object> { { "tmdname", name },{ "schooName", schoolBase.name } });
+                                    new Dictionary<string, object> { { "tmdname", name },{ "schooName", schoolBase.name } }, _option.Location, _configuration, _dingDing, "");
                                 _ = _azureStorage.SaveLog("transfer-admin-role", new { request, userid, name, school, schoolName = schoolBase.name, targetTecher = _targetTecher, }.ToJsonString(), bizId: $"{userid}-{schoolBase.id}-{_targetTecher}", httpContext: HttpContext, dingDing: _dingDing, scope: "school");
                                 return Ok(new { status = 1 });
                             }
@@ -1171,11 +1171,16 @@ namespace TEAMModelOS.Controllers
                         var val = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
                     }
                     if (teachers.IsNotEmpty()) {
-                        //string sql = $"select c.id, c.name ,c.lang as code from c where c.id in ({string.Join(",",teachers.Select(x=>$"'{x.id}'"))})";
-                        //_coreAPIHttpService.PushNotify(new List<IdNameCode> { new IdNameCode { id = targetTeacher.id, name = targetTeacher.name, code = targetTeacher.lang } }, $"{code}_school", Constant.NotifyType_IES5_Management,
-                        //          new Dictionary<string, object> { { "tmdname", name }, { "schooName", schoolBase.name } });
+                        string sql = $"select c.id, c.name ,c.lang as code from c where c.id in ({string.Join(",", teachers.Select(x => $"'{x.id}'"))})";
+                        List<IdNameCode> idNameCodes = new List<IdNameCode>();
+                        await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
+                            .GetItemQueryIterator<IdNameCode>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") })) 
+                        {
+                            idNameCodes.Add(item);
+                        }
+                        _coreAPIHttpService.PushNotify(idNameCodes, $"{code}_school", Constant.NotifyType_IES5_Management,
+                                  new Dictionary<string, object> { { "tmdname", name }, { "schooName", schoolBase.name } }, _option.Location,_configuration,_dingDing, "") ;
                     }
-                      
                     return Ok(new { stauts = 1 });
                 }
             }