Browse Source

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

zhouj1203@hotmail.com 1 year ago
parent
commit
d99dd980ce

+ 1 - 0
TEAMModelContest/contest.client/src/view/activitylist/ActivityInfo.less

@@ -167,6 +167,7 @@
                         // border-top: 1px dashed #ccc;
                         display: flex;
                         justify-content: center;
+                        flex-wrap: wrap;
 
                         &>div {
                             text-align: center;

+ 1 - 0
TEAMModelContest/contest.client/src/view/myactivity/MyActivity.less

@@ -125,6 +125,7 @@
                 // border-top: 1px dashed #ccc;
                 display: flex;
                 justify-content: center;
+                flex-wrap: wrap;
 
                 &>div {
                     text-align: center;

+ 26 - 1
TEAMModelOS.FunctionV4/CosmosDB/TriggerSurvey.cs

@@ -22,6 +22,7 @@ using HTEXLib.COMM.Helpers;
 using Microsoft.Extensions.Configuration;
 using System.Linq;
 using TEAMModelOS.SDK.Models.Service.BI;
+using Newtonsoft.Json;
 
 namespace TEAMModelOS.FunctionV4
 {
@@ -420,7 +421,31 @@ namespace TEAMModelOS.FunctionV4
                             {
                                 await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查问题结算异常{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
                             }
-                            var cods = new { records = recs, userids, question = questionRecords, urecord = surveyRecords };
+
+                            List<AnswerRecord> answerRecords = new List<AnswerRecord>();
+                            if (questionRecords.IsNotEmpty())
+                            {
+
+                               
+                                foreach (var questionRecord in questionRecords)
+                                {
+                                    AnswerRecord answerRecord = new AnswerRecord();
+                                    answerRecord.index = questionRecord.index.ToString();
+
+                                    foreach (var opt in questionRecord.opt)
+                                    {
+                                        if (!answerRecord.ans.ContainsKey(opt.Key))
+                                        {
+                                            answerRecord.ans[opt.Key] = 0;
+                                        }
+                                        answerRecord.ans[opt.Key] += opt.Value.Count;
+                                    }
+
+                                    answerRecords.Add(answerRecord);
+                                }
+                                //string resultJson = JsonConvert.SerializeObject(answerRecords, Formatting.Indented);
+                            }
+                            var cods = new { records = answerRecords, userids, question = questionRecords, urecord = surveyRecords };
                             //问卷整体情况
                             await _azureStorage.GetBlobContainerClient(blobcntr).UploadFileByContainer(cods.ToJsonString(), "survey", $"{survey.id}/record.json");
 

+ 5 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/Inner/QuestionRecord.cs

@@ -10,4 +10,9 @@ namespace TEAMModelOS.SDK.Models
         public Dictionary<string, HashSet<string>> opt { get; set; } = new Dictionary<string, HashSet<string>>();
         public Dictionary<string, string> other { get; set; } = new Dictionary<string, string>();
     }
+    public class AnswerRecord
+    {
+        public string index { get; set; }
+        public Dictionary<string, int> ans { get; set; } = new Dictionary<string, int>();
+    }
 }

+ 169 - 2
TEAMModelOS.SDK/Models/Service/Common/ActivityService.cs

@@ -13,10 +13,12 @@ using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
+using System.Net.Http;
 using System.Net.NetworkInformation;
 using System.Text;
 using System.Text.Json;
 using System.Threading.Tasks;
+using TEAMModelOS.Models;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models;
@@ -29,6 +31,167 @@ namespace TEAMModelOS.SDK
     public static class ActivityService
     {
 
+
+       public static  async Task<List<ExpertDto>> ListExperts(AzureCosmosFactory _azureCosmos ,CoreAPIHttpService _coreAPIHttpService,DingDing _dingDing, Option _option, string _activityId) {
+            List<ExpertDto> expertTasks = new List<ExpertDto>();
+            ActivityExpert activityExpert = null;
+
+            Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync($"{_activityId}", new PartitionKey("ActivityExpert"));
+            if (response.Status == 200)
+            {
+                bool change = false;
+                activityExpert = JsonDocument.Parse(response.Content).RootElement.Deserialize<ActivityExpert>();
+                var experts = activityExpert.experts.FindAll(z => string.IsNullOrWhiteSpace(z.id));
+                var tmdids = experts.Where(x => !string.IsNullOrWhiteSpace(x.tmdid)).Select(z => z.tmdid);
+                var phones = experts.Where(x => !string.IsNullOrWhiteSpace(x.mobile)).Select(z => z.mobile);
+                var emails = experts.Where(x => !string.IsNullOrWhiteSpace(x.email)).Select(z => z.email);
+                List<string> keys = new List<string>();
+                if (tmdids.Any())
+                {
+                    keys.AddRange(tmdids);
+                }
+                if (phones.Any())
+                {
+                    keys.AddRange(phones);
+                }
+                if (emails.Any())
+                {
+                    keys.AddRange(emails);
+                }
+                List<CoreUser> coreUsers = new List<CoreUser>();
+                if (keys.Any())
+                {
+                    try
+                    {
+                        var content = new StringContent(keys.ToJsonString(), Encoding.UTF8, "application/json");
+                        string json = await _coreAPIHttpService.GetUserInfos(content);
+                        if (!string.IsNullOrWhiteSpace(json))
+                        {
+                            coreUsers = json.ToObject<List<CoreUser>>();
+                        }
+                    }
+                    catch (Exception ex)
+                    {
+                        await _dingDing.SendBotMsg($"{_option.Location},导入名单时,查验key信息错误{ex.Message}\n{ex.StackTrace}\n\n{keys.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+                    }
+                }
+                if (coreUsers.IsNotEmpty())
+                {
+                    foreach (var t in experts)
+                    {
+                        if (!string.IsNullOrWhiteSpace(t.tmdid))
+                        {
+                            CoreUser coreUser = coreUsers.Find(x => x.id.Equals(t.tmdid));
+                            if (coreUser != null)
+                            {
+                                change=true;
+                                t.id = coreUser.id;
+                                t.name = coreUser.name;
+                                t.picture = coreUser.picture;
+                                t.tmdid = coreUser.id;
+                                if (!string.IsNullOrWhiteSpace(coreUser.mobile))
+                                {
+                                    t.mobile = coreUser.mobile;
+                                }
+                                if (!string.IsNullOrWhiteSpace(coreUser.mail))
+                                {
+                                    t.email = coreUser.mail;
+                                }
+                            }
+                        }
+                        if (string.IsNullOrWhiteSpace(t.id))
+                        {
+                            if (!string.IsNullOrWhiteSpace(t.mobile))
+                            {
+                                CoreUser coreUser = coreUsers.Find(x => !string.IsNullOrWhiteSpace(x.mobile) && x.mobile.Equals(t.mobile));
+                                if (coreUser != null)
+                                {
+                                    change=true;
+                                    t.id = coreUser.id;
+                                    t.name = coreUser.name;
+                                    t.picture = coreUser.picture;
+                                    t.tmdid = coreUser.id;
+                                    if (!string.IsNullOrWhiteSpace(coreUser.mobile))
+                                    {
+                                        t.mobile = coreUser.mobile;
+                                    }
+                                    if (!string.IsNullOrWhiteSpace(coreUser.mail))
+                                    {
+                                        t.email = coreUser.mail;
+                                    }
+                                }
+                            }
+                        }
+                        if (string.IsNullOrWhiteSpace(t.id))
+                        {
+                            if (!string.IsNullOrWhiteSpace(t.email))
+                            {
+                                CoreUser coreUser = coreUsers.Find(x => !string.IsNullOrWhiteSpace(x.mail) && x.mail.Equals(t.email));
+                                if (coreUser != null)
+                                {
+                                    change=true;
+                                    t.id = coreUser.id;
+                                    t.name = coreUser.name;
+                                    t.picture = coreUser.picture;
+                                    t.tmdid = coreUser.id;
+                                    if (!string.IsNullOrWhiteSpace(coreUser.mobile))
+                                    {
+                                        t.mobile = coreUser.mobile;
+                                    }
+                                    if (!string.IsNullOrWhiteSpace(coreUser.mail))
+                                    {
+                                        t.email = coreUser.mail;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                if (change)
+                {
+                    await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(activityExpert, new PartitionKey("ActivityExpert"));
+                }
+
+                Contest contest = null;
+                Azure.Response contestResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId, new PartitionKey("Contest"));
+                if (contestResponse.Status==200)
+                {
+                    contest = JsonDocument.Parse(contestResponse.Content).RootElement.ToObject<Contest>();
+                }
+                List<ExpertDto> expertDtos = activityExpert.experts.Select(z => z.ToJsonString().ToObject<ExpertDto>()).ToList();
+                long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
+                //进入评审环节
+                if (contest.review!= null  && now > contest.review.stime)
+                {
+
+                    if (expertDtos!=null  && expertDtos.Count()>0)
+                    {
+                        var hasIds = expertDtos.Where(x => !string.IsNullOrWhiteSpace(x.id));
+                        if (hasIds!=null  && hasIds.Count()>0)
+                        {
+                            string taskSql = $"select value c from c where c.id in ({string.Join(",", hasIds.Select(z => $"'{z.id}'"))})";
+                            var taskResults = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(taskSql, $"ActivityExpertTask-{_activityId}");
+
+                            foreach (var item in taskResults.list)
+                            {
+                                var dto = expertDtos.Find(z => !string.IsNullOrWhiteSpace(z.id)  &&  z.id.Equals(item.id));
+                                if (dto!=null)
+                                {
+                                    dto.taskCount =item.contestTasks.Count();
+                                    dto.teacherCount=item.contestTasks.SelectMany(z => z.members).Count();
+                                    dto.completeCount=item.contestTasks.Where(z => z.status==1).Count();
+                                    dto.uploads=  item.contestTasks.Select(z => new ContestUploadData { name = z.name, id=z.uploadId, code=string.Join(",", z.uploadTypes), count=z.count, status= z.status, score=z.score, detailScore=z.detailScore }).ToList();
+                                }
+                            }
+                        }
+                    }
+                }
+                expertTasks.AddRange(expertDtos);
+            }
+       
+            return expertTasks;
+        }
+
         public static async Task<List<ActivityScoreLevel>> ActivityScores (AzureCosmosFactory _azureCosmos,JsonElement _activityId,string teacherId= null) {
             List<ActivityScoreLevel> scoreLevels = new List<ActivityScoreLevel>();
             Azure.Response responseContest = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
@@ -136,17 +299,21 @@ namespace TEAMModelOS.SDK
                                     scoreLevels.Add(new ActivityScoreLevel { lable=level.lable });
                                     foreach (var item in teacherScores)
                                     {
+                                        if (item.score==80) 
+                                        {
+                                            Console.Write(1);
+                                        }
                                         string label = string.Empty;
                                         if (level.max==100)
                                         {
-                                            if (item.score>level.min  && item.score<=level.max)
+                                            if (item.score>=level.min  && item.score<=level.max)
                                             {
                                                 label=level.lable;
                                             }
                                         }
                                         else
                                         {
-                                            if (item.score>level.min  && item.score<level.max)
+                                            if (item.score>=level.min  && item.score<level.max)
                                             {
                                                 label=level.lable;
                                             }

+ 2 - 1
TEAMModelOS/ClientApp/package.json

@@ -4,7 +4,7 @@
   "private": true,
   "scripts": {
     "serve": "vue-cli-service serve",
-    "build": "vue-cli-service build --report",
+    "build": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
     "fix-memory-limit": "cross-env LIMIT=4096 increase-memory-limit",
     "lint": "vue-cli-service lint"
   },
@@ -51,6 +51,7 @@
     "lodash": "^4.17.21",
     "node-fetch": "^2.6.1",
     "oidc-client": "^1.9.1",
+    "pdfjs-dist": "^2.2.228",
     "primeicons": "^6.0.1",
     "primevue": "^2.10.1",
     "qrcodejs2": "0.0.2",

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

@@ -1585,6 +1585,7 @@ const LANG_EN_US = {
     // 试题试卷
     evaluation: {
         quickPaper: {
+            maxCountTip: 'The imported pages plus existing attachment exceeds the allowable amount, only the first few pages are retained!',
             title: 'Quick Design',
             mode1: 'Switch to flexible quick design',
             mode2: 'Switch to quick design by question type',
@@ -1611,7 +1612,7 @@ const LANG_EN_US = {
             ans: 'Answer',
             tip6: 'Enter the answer',
             tip7: 'Switching will clear the current question data, do you confirm to switch?',
-            tip8: 'Maximum 20 questions!',
+            tip8: 'Maximum 50 questions!',
             tip9: 'Enter the speaking prompt',
             tip10: 'The number of questions cannot be 0!',
             tip11: 'The number of answers for single answer questions does not match the number of questions, please check and retry!',

+ 2 - 1
TEAMModelOS/ClientApp/public/lang/zh-CN.js

@@ -1584,6 +1584,7 @@ const LANG_ZH_CN = {
     // 试题试卷
     evaluation: {
         quickPaper:{
+            maxCountTip:'导入的页数与现有附件合计后超过容许量, 仅保留前几页!',
             title:'快速组卷',
             mode1:'切换到自由快速组卷',
             mode2:'切换到题型快速组卷',
@@ -1611,7 +1612,7 @@ const LANG_ZH_CN = {
             tip6:'输入题目答案',
             tip7:'切换模式将会清空当前试题数据,是否确认切换?',
             tip13:'切换模式将会清空当前客观题答案,是否确认切换?',
-            tip8:'最多添加20道试题',
+            tip8:'最多添加50道试题',
             tip9:'输入音频题正确答案',
             tip10:'试题数量不可为空!',
             tip11: '单选题答案数与题目数不一致,请检查后重试!',

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

@@ -1587,6 +1587,7 @@ const LANG_ZH_TW = {
     // 试题试卷
     evaluation: {
         quickPaper: {
+            maxCountTip: '匯入的頁數與現有附件合計超過容許量, 僅保留前幾頁!',
             title: '快速組卷',
             mode1: '切換到自由快速組卷',
             mode2: '切換到題型快速組卷',
@@ -1613,7 +1614,7 @@ const LANG_ZH_TW = {
             ans: '參考答案',
             tip6: '輸入題目答案',
             tip7: '切換模式將會清除目前試題資料,是否確認切換? ',
-            tip8: '最多增加20個試題',
+            tip8: '最多增加50個試題',
             tip9: '輸入錄音題文字提示',
             tip10: '試題數量不可為0!',
             tip11: '單選題答案數與題目數不一致,請檢查後重試!',

+ 70 - 31
TEAMModelOS/ClientApp/src/common/BaseQuickPaper.vue

@@ -1,7 +1,7 @@
 <template>
 	<div class="quick-paper-container">
 		<p style="float: right; cursor: pointer; color: #4d9cdc" @click="onChangeMode">{{ buildMode === "type" ? $t("evaluation.quickPaper.mode1") : $t("evaluation.quickPaper.mode2") }}</p>
-		<p class="title" @click="loadPdfFile">{{ $t("evaluation.quickPaper.info") }}</p>
+		<p class="title">{{ $t("evaluation.quickPaper.info") }}</p>
 		<Input v-model="paperInfo.name" v-special-char :placeholder="$t('evaluation.quickPaper.tip1')" />
 		<div v-if="isSchool && schoolInfo">
 			<Select v-model="paperInfo.periodIndex" @on-change="onPeriodChange" style="width: 200px; margin-right: 15px; margin-top: 15px">
@@ -22,7 +22,7 @@
 		</div>
 		<p class="title">
 			{{ $t("evaluation.quickPaper.attachments") }}
-			<Upload action="" style="display: inline-block" accept="image/*" :format="['jpg', 'jpeg', 'png']" :max-size="2048" multiple :before-upload="handleBeforeUpload" :show-upload-list="false">
+			<Upload action="" style="display: inline-block" :format="['jpg', 'jpeg', 'png', 'pdf']" :max-size="2048" multiple :before-upload="handleBeforeUpload" :show-upload-list="false">
 				<span class="btn-upload">{{ $t("evaluation.quickPaper.upload") }}</span>
 			</Upload>
 		</p>
@@ -94,7 +94,7 @@
 								<Option value="ko-KR">{{ $t("evaluation.newExercise.answerType.kr") }}(ko-KR)</Option>
 								<Option value="zh-HK">{{ $t("evaluation.newExercise.answerType.hk") }}(zh-HK)</Option>
 							</Select>
-							<Input v-model="item.answer" :placeholder="$t('evaluation.quickPaper.tip9')" style="width: 405px" />
+							<Input v-model="item.answer" :placeholder="$t('evaluation.quickPaper.tip9')" style="width: 350px" />
 						</div>
 					</div>
 				</div>
@@ -122,7 +122,7 @@
 							<span>{{ typeMap[item.type] }}</span>
 						</span>
 						<span v-if="item.type === 'single' || item.type === 'multiple'">{{ $t("evaluation.quickPaper.options") }}:</span>
-						<Select v-model="item.options" style="width: 80px; margin: 0 10px" v-if="item.type === 'single' || item.type === 'multiple'">
+						<Select v-model="item.options" style="width: 80px; margin: 0 10px" v-if="item.type === 'single' || item.type === 'multiple'" transfer>
 							<Option v-for="(item, index) in 8" :value="index + 2" :key="index + 2">{{ index + 2 }}</Option>
 						</Select>
 						<span v-if="item.type === 'subjective'">
@@ -160,6 +160,8 @@
 <script>
 	import JsPDF from "jspdf";
 	import blobTool from "@/utils/blobTool.js";
+	import * as pdfjs from "pdfjs-dist";
+	import * as pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
 	export default {
 		props: {
 			editPaper: {
@@ -175,6 +177,7 @@
 					complete: this.$t("evaluation.complete"),
 					subjective: this.$t("evaluation.subjective")
 				},
+				maxAttachmentsCount:5,
 				answerInputMode: "number",
 				buildMode: "type",
 				schoolInfo: null,
@@ -206,11 +209,43 @@
 			});
 		},
 		methods: {
-			loadPdfFile() {
-				let PDF = new JsPDF();
-				let pdfUrl = "https://winteachtest.blob.core.chinacloudapi.cn/0-public/Images.pdf";
-				let result = PDF.loadFile(pdfUrl, true);
-				console.log(result);
+			async loadPdfFile(file) {
+				let that = this;
+				var reader = new FileReader();
+				reader.readAsDataURL(file); //将文件读取为 DataURL
+				reader.onload = function () {
+					//文件读取成功完成时触发
+					const loadingTask = pdfjs.getDocument(reader.result);
+					loadingTask.promise.then((pdf) => {
+						var pageNum = pdf.numPages;
+						let leftCount = that.maxAttachmentsCount - that.attachments.length - pageNum
+						if(leftCount < 0){
+							that.$Message.warning('evaluation.quickPaper.maxCountTip')
+							pageNum = that.maxAttachmentsCount - that.attachments.length
+						}
+						for (let i = 1; i <= pageNum; i++) {
+							pdf.getPage(i).then((page) => {
+								const canvas = document.createElement("canvas");
+								const ctx = canvas.getContext("2d");
+								const viewport = page.getViewport({ scale: 4 });
+								canvas.height = viewport.height;
+								canvas.width = viewport.width;
+								const destWidth = 398;
+								canvas.style.width = destWidth + "px";
+								canvas.style.height = destWidth * (viewport.height / viewport.width) + "px";
+								const renderTask = page.render({
+									canvasContext: ctx,
+									viewport
+								});
+								renderTask.promise.then(() => {
+									const imgUrl = canvas.toDataURL("image/jpeg");
+									console.log(imgUrl);
+									that.attachments.push(imgUrl);
+								});
+							});
+						}
+					});
+				};
 			},
 			/* 选项输入模式切换 */
 			onInputModeChange() {
@@ -291,7 +326,7 @@
 			},
 			/* 手动添加试题 */
 			doAddItem(type) {
-				if (this.orderItemsArr.length >= 20) {
+				if (this.orderItemsArr.length >= 50) {
 					this.$Message.warning(this.$t("evaluation.quickPaper.tip8"));
 					return;
 				}
@@ -438,9 +473,9 @@
 					}
 				}
 			},
-			codeOrder(str,type) {
-				if(type === 'single'){
-					return str
+			codeOrder(str, type) {
+				if (type === "single") {
+					return str;
 				}
 				const order = ["A", "B", "C", "D", "E", "F", "G", "H", "I"];
 				// 创建字母到索引的映射
@@ -466,9 +501,9 @@
 					let newStr = "";
 					if (!allowedChars.includes(val.data) && !isDel) {
 						// 如果最后输入的字符不在允许的数组中,则阻止输入
-						newStr = this.codeOrder(fullAnsStr.slice(0, -1 * newStrLength),type);
+						newStr = this.codeOrder(fullAnsStr.slice(0, -1 * newStrLength), type);
 					} else {
-						newStr = this.codeOrder(fullAnsStr,type);
+						newStr = this.codeOrder(fullAnsStr, type);
 					}
 					this.$nextTick(() => {
 						if (this.buildMode === "type") {
@@ -496,7 +531,7 @@
 							this.$set(this.multipleAns, index, sortVal);
 						}
 					} else {
-						this.$set(this.orderItemsArr[index], "answer", type === "single" ?  fullAnsStr : sortVal);
+						this.$set(this.orderItemsArr[index], "answer", type === "single" ? fullAnsStr : sortVal);
 					}
 				}
 			},
@@ -544,13 +579,15 @@
 			},
 			/* 上传附件 */
 			handleBeforeUpload(file) {
-				const check = this.attachments.length < 5;
+				console.error(file);
+				const check = this.attachments.length < this.maxAttachmentsCount;
 				if (!check) {
-					this.$Message.warning("最多上传5个附件");
+					this.$Message.warning(this.$t('vote.form.attachmentMaxTip'));
 					return;
 				}
 				const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png";
-				if (!isJpgOrPng) {
+				const isPdf = file.type === "application/pdf";
+				if (!isJpgOrPng && !isPdf) {
 					this.$Message.warning(this.$t("cusMgt.batch.tips3"));
 					return;
 				}
@@ -560,6 +597,10 @@
 					return;
 				}
 				let that = this;
+				if (isPdf) {
+					this.loadPdfFile(file);
+					return;
+				}
 				function getBase64(img) {
 					const reader = new FileReader();
 					reader.addEventListener("load", () => {
@@ -589,18 +630,10 @@
 							useAutoScore: false
 						});
 					}
-				}else if(type.type === 'complete'){
-					this.completeAns = [];
-                    for (var i = 0; i < type.count; i++) {
-                        this.completeAns.push({
-                            answerType: "text",
-                            answerLang: "zh",
-                            answer: "",
-                            useAutoScore: false
-                        });
-                    }
-				}else if(type.type === 'multiple'){
-					this.multipleAns = this.multipleAns.slice(0,type.count)
+				} else if (type.type === "complete") {
+					this.completeAns = this.completeAns.slice(0, type.count);
+				} else if (type.type === "multiple") {
+					this.multipleAns = this.multipleAns.slice(0, type.count);
 				}
 			},
 			/* 获取题目选项数据 */
@@ -972,6 +1005,11 @@
 				cursor: pointer;
 			}
 			.order-item {
+				.order{
+					display: inline-block;
+					width: 20px;
+					text-align: center;
+				}
 				.item-type {
 					display: inline-block;
 					background: #ededed;
@@ -1012,6 +1050,7 @@
 
 		.img-list {
 			display: flex;
+			flex-wrap: wrap;
 			img {
 				width: 120px;
 				margin-right: 10px;

+ 2 - 2
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperViewBox/PaperTest.vue

@@ -179,7 +179,7 @@
                                 <div class="answers-box">
                                     <!--判断题选项-->
                                     <div v-if="item.type == 'judge'" align="center">
-                                        <span>{{ index + 1 }}. </span>
+                                        <span style="font-weight: 900;">{{ index + 1 }}. </span>
                                         <label class="testBtn yesNoBtn">
                                             <input type="radio" value="A" v-model="checkers[index][0]" :disabled="!closeTest" />
                                             <div class="testbg" :style="{'background-color': isWrong && showEnd && checkers[index][0] === 'A' ? (item.answer[0] === 'A' ? '' : 'red !important') : ''}">
@@ -196,7 +196,7 @@
                                     </div>
                                     <!--选择题选项-->
                                     <div class="select-box" v-else-if="item.type === 'single' || item.type === 'multiple'">
-                                        <span>{{ index + 1 }}. </span>
+                                        <span style="font-weight: 900;">{{ index + 1 }}. </span>
                                         <label class="testBtn" v-for="(option, oIndex) in item.option" :key="oIndex">
                                             <input type="checkbox" :value="option.code" v-model="checkers[index]" @click="getAns(index, oIndex)" :disabled="!closeTest" />
                                             <div class="testbg">

+ 1 - 1
TEAMModelOS/ClientApp/src/view/signupActivity/infoComponent/skContent.vue

@@ -988,7 +988,7 @@ export default {
                         item.teamNameContest = item.teamNameContest || '-'
                         item.reviewNum = 0
                         item.reviewContestExperts.forEach(review => {
-                            if(review.score) item.reviewNum++
+                            if(review.score != -1) item.reviewNum++
                         })
                         return item
                     })

+ 29 - 163
TEAMModelOS/Controllers/Common/ActivityController.cs

@@ -1411,27 +1411,44 @@ namespace TEAMModelOS.Controllers
                                         // List<ActivityExpertTask> expertTasks = new List<ActivityExpertTask>();
                                         string taskSQL = $"select distinct value c from c  join s in c.contestTasks  where c.pk='ActivityExpertTask' and s.uploadId in ({string.Join(",", uploadContestIds.Select(z => $"'{z}'"))})";
                                         List<ExpertContestTaskDto> worksDB = new List<ExpertContestTaskDto>();
+                                       
                                         var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(taskSQL, $"ActivityExpertTask-{_activityId}");
                                         if (result.list.IsNotEmpty())
                                         {
+                                            List<ActivityExpertTask> change = new List<ActivityExpertTask>();
+                                            var experts = await ActivityService.ListExperts(_azureCosmos, _coreAPIHttpService, _dingDing, _option, $"{_activityId}");
                                             foreach (var item in result.list)
                                             {
-                                                foreach (var task in item.contestTasks)
+                                                var expert= experts.Find(x => !string.IsNullOrWhiteSpace(x.id) &&  x.id.Equals(item.id));
+                                                if (expert!=null) 
                                                 {
-                                                    var teachers = inviteEnrollTeachers.FindAll(z => !string.IsNullOrWhiteSpace(z.uploadContestId) && z.uploadContestId.Equals(task.uploadId));
-                                                    if (teachers!=null)
+                                                    foreach (var task in item.contestTasks)
                                                     {
-                                                        teachers.ForEach(z => { z.reviewContestAssignCount+=1; z.reviewContestExperts.Add(new ExpertUploadScore 
+                                                        var teachers = inviteEnrollTeachers.FindAll(z => !string.IsNullOrWhiteSpace(z.uploadContestId) && z.uploadContestId.Equals(task.uploadId));
+                                                        if (teachers!=null)
                                                         {
-                                                            score=task.score,
-                                                            detailScore=task.detailScore,
-                                                            id= item.id,
-                                                            name=item.name,
-                                                            nickname=item.tmdname,
-                                                            picture=item.picture
-                                                        }); });
+                                                            teachers.ForEach(z => {
+                                                                z.reviewContestAssignCount+=1;
+                                                                z.reviewContestExperts.Add(new ExpertUploadScore
+                                                                {
+                                                                    score=task.score,
+                                                                    detailScore=task.detailScore,
+                                                                    id= item.id,
+                                                                    name=item.name,
+                                                                    nickname=item.tmdname,
+                                                                    picture=item.picture
+                                                                });
+                                                            });
+                                                        }
                                                     }
                                                 }
+                                                else
+                                                {
+                                                    change.Add(item);
+                                                }
+                                            }
+                                            if (change.IsNotEmpty()) {
+                                              await  _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).DeleteItemsAsync<ActivityExpertTask>(change.Select(x=>x.id).ToList(),$"ActivityExpertTask-{_activityId}");
                                             }
                                         }
                                     }
@@ -1693,158 +1710,7 @@ namespace TEAMModelOS.Controllers
                     case bool when $"{grant_type}".Equals("list-experts", StringComparison.OrdinalIgnoreCase):
                         {
                             if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
-                            ActivityExpert activityExpert = null;
-                            List<ExpertDto> expertTasks = new List<ExpertDto>();
-                            Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync($"{_activityId}", new PartitionKey("ActivityExpert"));
-                            if (response.Status == 200)
-                            {
-                                bool change = false;
-                                activityExpert = JsonDocument.Parse(response.Content).RootElement.Deserialize<ActivityExpert>();
-                                var experts = activityExpert.experts.FindAll(z => string.IsNullOrWhiteSpace(z.id));
-                                var tmdids = experts.Where(x => !string.IsNullOrWhiteSpace(x.tmdid)).Select(z => z.tmdid);
-                                var phones = experts.Where(x => !string.IsNullOrWhiteSpace(x.mobile)).Select(z => z.mobile);
-                                var emails = experts.Where(x => !string.IsNullOrWhiteSpace(x.email)).Select(z => z.email);
-                                List<string> keys = new List<string>();
-                                if (tmdids.Any())
-                                {
-                                    keys.AddRange(tmdids);
-                                }
-                                if (phones.Any())
-                                {
-                                    keys.AddRange(phones);
-                                }
-                                if (emails.Any())
-                                {
-                                    keys.AddRange(emails);
-                                }
-                                List<CoreUser> coreUsers = new List<CoreUser>();
-                                if (keys.Any())
-                                {
-                                    try
-                                    {
-                                        var content = new StringContent(keys.ToJsonString(), Encoding.UTF8, "application/json");
-                                        string json = await _coreAPIHttpService.GetUserInfos(content);
-                                        if (!string.IsNullOrWhiteSpace(json))
-                                        {
-                                            coreUsers = json.ToObject<List<CoreUser>>();
-                                        }
-                                    }
-                                    catch (Exception ex)
-                                    {
-                                        await _dingDing.SendBotMsg($"{_option.Location},导入名单时,查验key信息错误{ex.Message}\n{ex.StackTrace}\n\n{keys.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-                                    }
-                                }
-                                if (coreUsers.IsNotEmpty())
-                                {
-                                    foreach (var t in experts)
-                                    {
-                                        if (!string.IsNullOrWhiteSpace(t.tmdid))
-                                        {
-                                            CoreUser coreUser = coreUsers.Find(x => x.id.Equals(t.tmdid));
-                                            if (coreUser != null)
-                                            {
-                                                change=true;
-                                                t.id = coreUser.id;
-                                                t.name = coreUser.name;
-                                                t.picture = coreUser.picture;
-                                                t.tmdid = coreUser.id;
-                                                if (!string.IsNullOrWhiteSpace(coreUser.mobile))
-                                                {
-                                                    t.mobile = coreUser.mobile;
-                                                }
-                                                if (!string.IsNullOrWhiteSpace(coreUser.mail))
-                                                {
-                                                    t.email = coreUser.mail;
-                                                }
-                                            }
-                                        }
-                                        if (string.IsNullOrWhiteSpace(t.id))
-                                        {
-                                            if (!string.IsNullOrWhiteSpace(t.mobile))
-                                            {
-                                                CoreUser coreUser = coreUsers.Find(x => !string.IsNullOrWhiteSpace(x.mobile) && x.mobile.Equals(t.mobile));
-                                                if (coreUser != null)
-                                                {
-                                                    change=true;
-                                                    t.id = coreUser.id;
-                                                    t.name = coreUser.name;
-                                                    t.picture = coreUser.picture;
-                                                    t.tmdid = coreUser.id;
-                                                    if (!string.IsNullOrWhiteSpace(coreUser.mobile))
-                                                    {
-                                                        t.mobile = coreUser.mobile;
-                                                    }
-                                                    if (!string.IsNullOrWhiteSpace(coreUser.mail))
-                                                    {
-                                                        t.email = coreUser.mail;
-                                                    }
-                                                }
-                                            }
-                                        }
-                                        if (string.IsNullOrWhiteSpace(t.id))
-                                        {
-                                            if (!string.IsNullOrWhiteSpace(t.email))
-                                            {
-                                                CoreUser coreUser = coreUsers.Find(x => !string.IsNullOrWhiteSpace(x.mail) && x.mail.Equals(t.email));
-                                                if (coreUser != null)
-                                                {
-                                                    change=true;
-                                                    t.id = coreUser.id;
-                                                    t.name = coreUser.name;
-                                                    t.picture = coreUser.picture;
-                                                    t.tmdid = coreUser.id;
-                                                    if (!string.IsNullOrWhiteSpace(coreUser.mobile))
-                                                    {
-                                                        t.mobile = coreUser.mobile;
-                                                    }
-                                                    if (!string.IsNullOrWhiteSpace(coreUser.mail))
-                                                    {
-                                                        t.email = coreUser.mail;
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                                if (change)
-                                {
-                                    await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(activityExpert, new PartitionKey("ActivityExpert"));
-                                }
-
-                                Contest contest = null;
-                                Azure.Response contestResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("Contest"));
-                                if (contestResponse.Status==200)
-                                {
-                                    contest = JsonDocument.Parse(contestResponse.Content).RootElement.ToObject<Contest>();
-                                }
-                                List<ExpertDto> expertDtos = activityExpert.experts.Select(z => z.ToJsonString().ToObject<ExpertDto>()).ToList();
-                                long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
-                                //进入评审环节
-                                if (contest.review!= null  && now > contest.review.stime) {
-                                  
-                                    if (expertDtos!=null  && expertDtos.Count()>0)
-                                    {
-                                        var hasIds = expertDtos.Where(x => !string.IsNullOrWhiteSpace(x.id));
-                                        if (hasIds!=null  && hasIds.Count()>0)
-                                        {
-                                            string taskSql = $"select value c from c where c.id in ({string.Join(",", hasIds.Select(z => $"'{z.id}'"))})";
-                                            var taskResults = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(taskSql, $"ActivityExpertTask-{_activityId}");
-
-                                            foreach (var item in taskResults.list) {
-                                                var dto = expertDtos.Find(z => !string.IsNullOrWhiteSpace(z.id)  &&  z.id.Equals(item.id));
-                                                if (dto!=null  )
-                                                {
-                                                    dto.taskCount =item.contestTasks.Count();
-                                                    dto.teacherCount=item.contestTasks.SelectMany(z => z.members).Count();
-                                                    dto.completeCount=item.contestTasks.Where(z => z.status==1).Count();
-                                                    dto.uploads=  item.contestTasks.Select(z => new ContestUploadData { name = z.name, id=z.uploadId, code=string.Join(",", z.uploadTypes), count=z.count,status= z.status,score=z.score, detailScore=z.detailScore }).ToList();
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                                expertTasks.AddRange(expertDtos);
-                            }
+                            var expertTasks = await  ActivityService.ListExperts(_azureCosmos, _coreAPIHttpService, _dingDing, _option, $"{_activityId}");
                             return Ok(new { expertTasks, code = 200 });
                         }
                     case bool when $"{grant_type}".Equals("update-reviewStatus", StringComparison.OrdinalIgnoreCase):