Prechádzať zdrojové kódy

Merge branch 'develop5.0' into TPE/develop5.0

jeff 3 rokov pred
rodič
commit
c8aad708c0
91 zmenil súbory, kde vykonal 2876 pridanie a 1324 odobranie
  1. 83 0
      TEAMModeBI/Controllers/BIHome/HomeStatisController.cs
  2. 225 0
      TEAMModeBI/Controllers/DingDingStruc/DDDeptController.cs
  3. 17 0
      TEAMModeBI/Controllers/DingDingStruc/DDPowerController.cs
  4. 530 0
      TEAMModeBI/Controllers/DingDingStruc/DDStructController.cs
  5. 1 1
      TEAMModeBI/Controllers/LoginController.cs
  6. 3 3
      TEAMModelFunction/TriggerExam.cs
  7. 41 0
      TEAMModelOS.SDK/Models/Cosmos/BI/DeptNode.cs
  8. 26 7
      TEAMModelOS.SDK/Models/Cosmos/Common/SheetConfig.cs
  9. 1 1
      TEAMModelOS.SDK/Models/Service/GroupListService.cs
  10. 1 1
      TEAMModelOS.SDK/Models/Service/StuListService.cs
  11. 49 3
      TEAMModelOS/ClientApp/src/assets/iconfont/demo_index.html
  12. 11 3
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.css
  13. 1 1
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.js
  14. 14 0
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.json
  15. BIN
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.ttf
  16. BIN
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.woff
  17. BIN
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.woff2
  18. 12 4
      TEAMModelOS/ClientApp/src/assets/student-web/component_styles/event-list.less
  19. 2 0
      TEAMModelOS/ClientApp/src/boot-app.js
  20. 2 2
      TEAMModelOS/ClientApp/src/common/BaseSelectSchool.vue
  21. 1 1
      TEAMModelOS/ClientApp/src/common/EmptyData.vue
  22. 5 3
      TEAMModelOS/ClientApp/src/common/HtexRender.vue
  23. 34 8
      TEAMModelOS/ClientApp/src/common/MyHTEXRender.vue
  24. 6 1
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.less
  25. 6 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue
  26. 2 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReportCharts/KeyPointPerformChart.vue
  27. 2 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReportCharts/RecognizePerformChart.vue
  28. 1 1
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.vue
  29. 4 3
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue
  30. 3 3
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/HomeView.vue
  31. 5 5
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/newHomeView.vue
  32. 48 35
      TEAMModelOS/ClientApp/src/css/site.css
  33. 1 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/evaluation.js
  34. 1 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/jyzx.js
  35. 5 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/stuAccount.js
  36. 2 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/studentWeb.js
  37. 1 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/evaluation.js
  38. 1 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/jyzx.js
  39. 5 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/stuAccount.js
  40. 2 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/studentWeb.js
  41. 1 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/evaluation.js
  42. 1 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/jyzx.js
  43. 5 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/stuAccount.js
  44. 2 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/studentWeb.js
  45. 9 0
      TEAMModelOS/ClientApp/src/router/routes.js
  46. 44 11
      TEAMModelOS/ClientApp/src/store/module/answerSheet.js
  47. 2 2
      TEAMModelOS/ClientApp/src/utils/evTools.js
  48. 129 22
      TEAMModelOS/ClientApp/src/utils/html2pdf.js
  49. 33 0
      TEAMModelOS/ClientApp/src/utils/public.js
  50. 1 1
      TEAMModelOS/ClientApp/src/utils/sheetConfig.js
  51. 3 3
      TEAMModelOS/ClientApp/src/view/Home.vue
  52. 4 4
      TEAMModelOS/ClientApp/src/view/ability/TestPaper.vue
  53. 13 0
      TEAMModelOS/ClientApp/src/view/areaMgmt/AreaBase.vue
  54. 16 18
      TEAMModelOS/ClientApp/src/view/classrecord/ClassRecord.less
  55. 548 588
      TEAMModelOS/ClientApp/src/view/classrecord/ClassRecord.vue
  56. 3 3
      TEAMModelOS/ClientApp/src/view/classrecord/CorrectRate.vue
  57. 19 19
      TEAMModelOS/ClientApp/src/view/classrecord/OptionCount.vue
  58. 82 68
      TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue
  59. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/bank/index.less
  60. 2 2
      TEAMModelOS/ClientApp/src/view/evaluation/bank/index.vue
  61. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/index/CommonExercise.less
  62. 3 14
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreateExercises.less
  63. 2 4
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue
  64. 2 1
      TEAMModelOS/ClientApp/src/view/evaluation/index/TestPaper.vue
  65. 2 2
      TEAMModelOS/ClientApp/src/view/jyzx/application.vue
  66. 3 3
      TEAMModelOS/ClientApp/src/view/learnactivity/ByQuMark.vue
  67. 2 2
      TEAMModelOS/ClientApp/src/view/learnactivity/ByStuMark.vue
  68. 1 1
      TEAMModelOS/ClientApp/src/view/learnactivity/ManualCreate.vue
  69. 1 1
      TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.less
  70. 7 5
      TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue
  71. 32 40
      TEAMModelOS/ClientApp/src/view/newsheet/BaseEditor.vue
  72. 13 24
      TEAMModelOS/ClientApp/src/view/newsheet/BaseSvgBg.vue
  73. 15 34
      TEAMModelOS/ClientApp/src/view/newsheet/SheetBaseInfo.vue
  74. 12 1
      TEAMModelOS/ClientApp/src/view/newsheet/SheetComplete.vue
  75. 16 11
      TEAMModelOS/ClientApp/src/view/newsheet/SheetObjective.vue
  76. 10 0
      TEAMModelOS/ClientApp/src/view/newsheet/SheetSubjective.vue
  77. 109 22
      TEAMModelOS/ClientApp/src/view/newsheet/index.vue
  78. 2 1
      TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue
  79. 15 11
      TEAMModelOS/ClientApp/src/view/resource/SourceCenter.vue
  80. 2 2
      TEAMModelOS/ClientApp/src/view/resource/SourceDetail.vue
  81. 12 1
      TEAMModelOS/ClientApp/src/view/settings/SchoolMgmt.less
  82. 3 2
      TEAMModelOS/ClientApp/src/view/settings/SchoolMgmt.vue
  83. 7 8
      TEAMModelOS/ClientApp/src/view/student-account/stuMgt/AddStudent.vue
  84. 2 0
      TEAMModelOS/ClientApp/src/view/student-web/App.vue
  85. 3 3
      TEAMModelOS/ClientApp/src/view/syllabus/Syllabus.vue
  86. 12 5
      TEAMModelOS/ClientApp/src/view/task/index.vue
  87. 206 0
      TEAMModelOS/ClientApp/src/view/task/mark/ByQu2.vue
  88. 11 16
      TEAMModelOS/ClientApp/src/view/task/mark/ByStu.vue
  89. 282 259
      TEAMModelOS/Controllers/Third/ScController.cs
  90. 4 4
      TEAMModelOS/TEAMModelOS.csproj
  91. 12 12
      TEAMModelOS/appsettings.Development.json

+ 83 - 0
TEAMModeBI/Controllers/BIHome/HomeStatisController.cs

@@ -0,0 +1,83 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Text.Json;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.Models;
+using Azure.Cosmos;
+using Microsoft.Extensions.Options;
+
+namespace TEAMModeBI.Controllers.BIHome
+{
+    [Route("homestatis")]
+    [ApiController]
+    public class HomeStatisController : ControllerBase
+    {
+        private readonly AzureCosmosFactory _azureCosmos;
+        private readonly DingDing _dingDing;
+        private readonly Option _option;
+
+        public HomeStatisController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option) 
+        {
+            _azureCosmos = azureCosmos;
+            _dingDing = dingDing;
+            _option = option?.Value;
+        }
+
+
+        /// <summary>
+        /// 获取人数
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("numberpeople")]
+        public async Task<IActionResult> NumberPeople(JsonElement jsonElement)  
+        {
+            if (!jsonElement.TryGetProperty("schooolId", out JsonElement schoolId)) return BadRequest();
+
+            var client = _azureCosmos.GetCosmosClient();
+
+            //依据学校查询教师人数
+            List<string> teacherCount_list = new();
+            await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIterator(queryText: $"select c.id from c join S1 in c.schools where S1.schoolId='{schoolId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") })) 
+            {
+                using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) 
+                {
+                    var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
+                    while (accounts.MoveNext()) 
+                    {
+                        JsonElement account = accounts.Current;
+                        teacherCount_list.Add(account.GetProperty("id").GetString());
+                    }
+                }
+            }
+
+            //
+            List<string> studentCount_List = new();
+            await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryStreamIterator(queryText: $"select c.id from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{schoolId}") })) 
+            {
+                using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                {
+                    var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
+                    while (accounts.MoveNext()) 
+                    {
+                        JsonElement account = accounts.Current;
+                        studentCount_List.Add(account.GetProperty("id").GetString());
+                    }
+                }
+            }
+
+
+
+            return Ok(new { SchoolTeacherCount = teacherCount_list.Count });
+
+
+        }
+    }
+}

+ 225 - 0
TEAMModeBI/Controllers/DingDingStruc/DDDeptController.cs

@@ -0,0 +1,225 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Configuration;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.Models;
+using DingTalk.Api;
+using DingTalk.Api.Request;
+using DingTalk.Api.Response;
+using TEAMModelOS.SDK.Models.Cosmos.BI;
+using System.Text.Json;
+using Azure.Cosmos;
+
+namespace TEAMModeBI.Controllers.DingDingStruc
+{
+    [Route("branch")]
+    [ApiController]
+    public class DDDeptController : ControllerBase
+    {
+        private readonly IConfiguration _configuration;
+        //数据容器
+        private readonly AzureCosmosFactory _azureCosmos;
+        //钉钉提示信息
+        private readonly DingDing _dingDing;
+        private readonly Option _option;
+
+        public DDDeptController(IConfiguration configuration,AzureCosmosFactory azureCosmos)
+        {
+            _configuration = configuration;
+            _azureCosmos = azureCosmos;
+        }
+
+        #region   从钉钉拿数据存CosmosDB中
+
+        /// <summary>
+        /// 获取部门机构
+        /// </summary>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("get-depts")]
+        public async Task<IActionResult> GetDDDepts() 
+        {
+            try
+            {
+                string appKey = _configuration["DingDingAuth:appKey"];
+                string appSecret = _configuration["DingDingAuth:appSecret"];
+                string agentld = _configuration["DingDingAuth:Agentld"];
+
+                //获取access_token
+                DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
+                OapiGettokenRequest request = new OapiGettokenRequest() { Appkey = appKey, Appsecret = appSecret };
+                request.SetHttpMethod("Get");
+                OapiGettokenResponse response = client.Execute(request);
+                if (response.IsError)
+                {
+                    return BadRequest();
+                }
+
+                //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
+                string access_token = response.AccessToken;
+
+                //获取一级部门列表
+                IDingTalkClient V2departClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
+                OapiV2DepartmentListsubRequest reqPartment1 = new OapiV2DepartmentListsubRequest() { DeptId = 1L, Language = "zh_CN" };
+                OapiV2DepartmentListsubResponse rspPartment1 = V2departClient.Execute(reqPartment1, access_token);
+                if (rspPartment1.IsError)
+                {
+                    return BadRequest();
+                }
+
+                DeptNode deptNodes = new DeptNode();
+                deptNodes.id = agentld;
+                deptNodes.code = "DDPartment";
+                deptNodes.pk = "DDPartment";
+                deptNodes.ttl = -1;
+
+                List<DeptInfo> deptlist = new List<DeptInfo>();
+                if (rspPartment1.Result != null) 
+                {
+                    foreach (var depts in rspPartment1.Result) 
+                    {
+                        DeptInfo deptInfo = new DeptInfo();
+                        deptInfo.id = depts.DeptId;
+                        deptInfo.pid = depts.ParentId;
+                        deptInfo.name = depts.Name;
+
+                        //获取一级部门用户列表
+                        IDingTalkClient userListClient1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
+                        OapiUserListidRequest reqUsers1 = new OapiUserListidRequest() { DeptId = depts.DeptId };
+                        OapiUserListidResponse rspUsers1 = userListClient1.Execute(reqUsers1, access_token);
+                        if (rspUsers1.Result != null)
+                        {
+                            deptInfo.users = rspUsers1.Result.UseridList;
+                        }
+
+                        //获取二级部门列表
+                        OapiV2DepartmentListsubRequest reqPartment2 = new OapiV2DepartmentListsubRequest() { DeptId = depts.DeptId, Language = "zh_CN" };
+                        OapiV2DepartmentListsubResponse rspPartment2 = V2departClient.Execute(reqPartment2, access_token);
+                        if (rspPartment2.Result != null)
+                        {
+                            foreach (var depts2 in rspPartment2.Result)
+                            {
+                                DeptInfo deptInfo2 = new DeptInfo();
+                                deptInfo2.id = depts2.DeptId;
+                                deptInfo2.pid = depts2.ParentId;
+                                deptInfo2.name = depts2.Name;
+
+                                //获取三级部门用户列表
+                                OapiUserListidRequest reqUsers2 = new OapiUserListidRequest() { DeptId = depts2.DeptId };
+                                OapiUserListidResponse rspUsers2 = userListClient1.Execute(reqUsers2, access_token);
+                                if (rspUsers2.Result != null)
+                                {
+                                    //添加三级部门用户
+                                    deptInfo2.users = rspUsers2.Result.UseridList;
+                                }
+
+                                //获取三级部门列表
+                                OapiV2DepartmentListsubRequest reqPartment3 = new OapiV2DepartmentListsubRequest() { DeptId = depts2.DeptId, Language = "zh_CN" };
+                                OapiV2DepartmentListsubResponse rspPartment3 = V2departClient.Execute(reqPartment3, access_token);
+                                if (rspPartment3.Result != null) 
+                                {
+                                    foreach (var depts3 in rspPartment3.Result) 
+                                    {
+                                        DeptInfo deptInfo3 = new DeptInfo();
+                                        deptInfo3.id = depts3.DeptId;
+                                        deptInfo3.pid = depts3.ParentId;
+                                        deptInfo3.name = depts3.Name;
+
+                                        //获取三级部门用户列表
+                                        OapiUserListidRequest reqUsers3 = new OapiUserListidRequest() { DeptId = depts3.DeptId };
+                                        OapiUserListidResponse rspUsers3 = userListClient1.Execute(reqUsers3, access_token);
+                                        if (rspUsers3.Result != null)
+                                        {
+                                            //添加三级部门用户
+                                            deptInfo3.users = rspUsers3.Result.UseridList;
+                                        }
+
+                                        //获取四级部门列表
+                                        OapiV2DepartmentListsubRequest reqPartment4 = new OapiV2DepartmentListsubRequest() { DeptId = depts3.DeptId, Language = "zh_CN" };
+                                        OapiV2DepartmentListsubResponse rspPartment4 = V2departClient.Execute(reqPartment4, access_token);
+                                        if (rspPartment4.Result != null)
+                                        {
+                                            foreach (var depts4 in rspPartment4.Result)
+                                            {
+                                                DeptInfo deptInfo4 = new DeptInfo();
+                                                deptInfo4.id = depts4.DeptId;
+                                                deptInfo4.pid = depts4.ParentId;
+                                                deptInfo4.name = depts4.Name;
+
+                                                //获取四级部门用户列表
+                                                OapiUserListidRequest reqUsers4 = new OapiUserListidRequest() { DeptId = depts4.DeptId };
+                                                OapiUserListidResponse rspUsers4 = userListClient1.Execute(reqUsers4, access_token);
+                                                if (rspUsers4.Result != null)
+                                                {
+                                                    //添加四级部门用户
+                                                    deptInfo4.users = rspUsers4.Result.UseridList;
+                                                }
+
+                                                deptlist.Add(deptInfo4);
+                                            }                                        
+                                        }
+                                        deptlist.Add(deptInfo3);
+                                    }
+                                }
+                                deptlist.Add(deptInfo2);
+                            }
+                        }
+                        deptlist.Add(deptInfo);
+                    }
+                }
+                deptNodes.depts = deptlist;
+                await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync<DeptNode>(deptNodes, new Azure.Cosmos.PartitionKey($"DDPartment"));
+
+                return Ok(new { state = 200, message = "钉钉的组织架构添加到数据库成功", deptNodes = deptNodes });
+            }
+            catch (Exception ex)
+            {
+                return Ok(new { state = 1, message = $"访问失败!状态:{ex.StackTrace} 错误:{ex.Message}" });
+            }
+        }
+
+        #endregion  
+
+        #region 从数据库获取(设置、修改、)钉钉组织架构信息
+
+        /// <summary>
+        /// 依据当前部门编号获取下级部门信息
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("get-partment")]
+        public async Task<IActionResult> GetPartment(JsonElement jsonElement)
+        {
+            try
+            {
+                if (!jsonElement.TryGetProperty("pid", out JsonElement pid)) return BadRequest();
+
+                var client = _azureCosmos.GetCosmosClient();              
+                List<DeptInfo> deptInfos = new List<DeptInfo>();
+                string sqltxt = $"select a1.id,a1.pid,a1.name,a1.users from c join a1 IN c.depts where a1.pid={pid}";
+                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<DeptInfo>(queryText: sqltxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("DDPartment") }))
+                {
+                    deptInfos.Add(item);
+                }
+
+                return Ok(new { state = 200, deptInfos });
+            }
+            catch (Exception ex)
+            {
+                return Ok(new { state = 1, message = $"访问失败! 状态:{ex.StackTrace} 错误:{ex.Message}" });
+            }
+        }
+
+
+
+
+
+
+        #endregion
+    }
+}

+ 17 - 0
TEAMModeBI/Controllers/DingDingStruc/DDPowerController.cs

@@ -0,0 +1,17 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TEAMModeBI.Controllers.DingDingStruc
+{
+    [Route("power")]
+    [ApiController]
+    public class DDPowerController : ControllerBase
+    {
+        //public 
+
+    }
+}

+ 530 - 0
TEAMModeBI/Controllers/DingDingStruc/DDStructController.cs

@@ -0,0 +1,530 @@
+using DingTalk.Api;
+using DingTalk.Api.Request;
+using DingTalk.Api.Response;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.Models;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Models.Service;
+
+namespace TEAMModeBI.Controllers.DingDingStruc
+{
+    [Route("dd")]
+    [ApiController]
+    public class DDStructController : ControllerBase
+    {
+        private readonly IConfiguration _configuration;
+        //数据容器
+        private readonly AzureCosmosFactory _azureCosmos;
+        //文件容器
+        private readonly AzureStorageFactory _azureStorage;
+        //钉钉提示信息
+        private readonly DingDing _dingDing;
+        private readonly Option _option;
+
+        public DDStructController(IConfiguration configuration, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, DingDing dingDing, IOptionsSnapshot<Option> option, CoreAPIHttpService aoreAPIHttpService)
+        {
+            _configuration = configuration;
+            _azureCosmos = azureCosmos;
+            _azureStorage = azureStorage;
+            _dingDing = dingDing;
+            _option = option?.Value;
+        }
+
+        /// <summary>
+        /// 获取组织架构列表
+        /// </summary>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("ddminstruc")]
+        public async Task<IActionResult> DDMainStruc()
+        {
+            string str_appKey = _configuration["DingDingAuth:appKey"];
+            string str_appSecret = _configuration["DingDingAuth:appSecret"];
+
+            //获取企业内部应用的accessToken
+            IDingTalkClient Iclient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
+            OapiGettokenRequest request = new OapiGettokenRequest();
+            request.Appkey = str_appKey;
+            request.Appsecret = str_appSecret;
+            request.SetHttpMethod("GET");
+            OapiGettokenResponse tokenResponse = Iclient.Execute(request);
+            if (tokenResponse.IsError)
+            {
+                return Ok(new { status = 0, message = "请检查配置" });
+            }
+            string access_token1 = tokenResponse.AccessToken;
+            IDingTalkClient dingTalkClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/org/union/trunk/get");
+            OapiOrgUnionTrunkGetRequest oapiOrgUnionTrunkGetRequest = new OapiOrgUnionTrunkGetRequest();
+            OapiOrgUnionTrunkGetResponse oapiOrgUnionTrunkGetResponse = dingTalkClient.Execute(oapiOrgUnionTrunkGetRequest, tokenResponse.AccessToken);
+
+            return Ok(new { oapiOrgUnionTrunkGetResponse.RequestId , oapiOrgUnionTrunkGetResponse.Body, oapiOrgUnionTrunkGetResponse.Result });
+
+        }
+
+        /// <summary>
+        /// 获取分支组织列表信息
+        /// </summary>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("ddbranchstruc")]
+        public async Task<IActionResult> DDBranchStruc()
+        {
+            string str_appKey = _configuration["DingDingAuth:appKey"];
+            string str_appSecret = _configuration["DingDingAuth:appSecret"];
+
+            //获取企业内部应用的accessToken
+            IDingTalkClient Iclient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
+            OapiGettokenRequest request = new OapiGettokenRequest();
+            request.Appkey = str_appKey;
+            request.Appsecret = str_appSecret;
+            request.SetHttpMethod("GET");
+            OapiGettokenResponse tokenResponse = Iclient.Execute(request);
+            if (tokenResponse.IsError)
+            {
+                return Ok(new { status = 0, message = "请检查配置" });
+            }
+            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/org/union/branch/get");
+            OapiOrgUnionBranchGetRequest req = new OapiOrgUnionBranchGetRequest();
+            OapiOrgUnionBranchGetResponse rsp = client.Execute(req, tokenResponse.AccessToken);
+
+
+            return Ok(new { Result = rsp.Result, Body = rsp.Body, RequestId = rsp.RequestId, SubErrCode = rsp.SubErrCode, Success = rsp.Success });
+        }
+
+
+        /// <summary>
+        /// 获取企业部门列表
+        /// </summary>
+        [ProducesDefaultResponseType]
+        [HttpPost("get-deptlist")]
+        public async Task<IActionResult>  GetDeptList()
+        {
+            try
+            {
+                string appKey = _configuration["DingDingAuth:appKey"];
+                string appSecret = _configuration["DingDingAuth:appSecret"];
+
+                //获取access_token
+                DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
+                OapiGettokenRequest request = new OapiGettokenRequest();
+                request.Appkey = appKey;
+                request.Appsecret = appSecret;
+                request.SetHttpMethod("Get");
+                OapiGettokenResponse response = client.Execute(request);
+                if (response.IsError)
+                {
+                    return BadRequest();
+                }
+
+                //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
+                string access_token = response.AccessToken;
+
+                //获取一级部门列表
+                IDingTalkClient v2ListsubClient1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
+                OapiV2DepartmentListsubRequest reqlistsub1 = new OapiV2DepartmentListsubRequest() { DeptId = 1L, Language = "zh_CN" };
+                OapiV2DepartmentListsubResponse rsplistsub1 = v2ListsubClient1.Execute(reqlistsub1, access_token);
+                List<DeptInfo> templsit = new List<DeptInfo>();
+
+                if (rsplistsub1.Result != null)
+                {
+                    foreach (var deptList in rsplistsub1.Result)
+                    {
+                        DeptInfo deptInfo = new DeptInfo();
+                        deptInfo.deptId = deptList.DeptId;
+                        deptInfo.deptName = deptList.Name;
+                        deptInfo.parentId = deptList.ParentId;
+
+                        //获取一级部门用户列表
+                        IDingTalkClient userListClient1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
+                        OapiUserListidRequest reqUserList1 = new OapiUserListidRequest() { DeptId = deptList.DeptId };
+                        OapiUserListidResponse rspUserList1 = userListClient1.Execute(reqUserList1, access_token);
+                        if (rspUserList1.Result != null)
+                        {
+                            deptInfo.ddUserList = rspUserList1.Result.UseridList;
+                        }
+
+                        //获取用户详细信息
+                        IDingTalkClient v2UserListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
+                        OapiV2UserGetRequest reqv2UserList = new OapiV2UserGetRequest();
+                        OapiV2UserGetResponse rspv2UserList = v2UserListClient.Execute(reqv2UserList, access_token);
+
+                        //获取二级部门列表
+                        OapiV2DepartmentListsubRequest reqlistsub = new OapiV2DepartmentListsubRequest() { DeptId = deptList.DeptId, Language = "zh_CN" };
+                        OapiV2DepartmentListsubResponse rsplistsub = v2ListsubClient1.Execute(reqlistsub, access_token);
+
+                        List<DeptBaseResponseDomain> deptBaseResponseDomainList = new List<DeptBaseResponseDomain>();
+                        if (rsplistsub.Result != null)
+                        {
+                            foreach (var deptlist2 in rsplistsub.Result)
+                            {
+                                //添加二级部门
+                                DeptBaseResponseDomain deptBaseResponseDomain2 = new DeptBaseResponseDomain();
+                                deptBaseResponseDomain2.deptId = deptlist2.DeptId;
+                                deptBaseResponseDomain2.Name = deptlist2.Name;
+                                deptBaseResponseDomain2.ParentId = deptlist2.ParentId;
+
+                                //获取三级部门用户列表
+                                OapiUserListidRequest reqUserList2 = new OapiUserListidRequest() { DeptId = deptlist2.DeptId };
+                                OapiUserListidResponse rspUserList2 = userListClient1.Execute(reqUserList2, access_token);
+                                if (rspUserList2.Result != null)
+                                {
+                                    //添加三级部门用户
+                                    deptBaseResponseDomain2.ddUserList = rspUserList2.Result.UseridList;
+                                }
+                                //获取三级部门列表
+                                OapiV2DepartmentListsubRequest reqlistsub3 = new OapiV2DepartmentListsubRequest() { DeptId = deptlist2.DeptId, Language = "zh_CN" };
+                                OapiV2DepartmentListsubResponse rsplistsub3 = v2ListsubClient1.Execute(reqlistsub3, access_token);
+
+                                List<DeptBaseResponseDomain> deptBaseResponseDomain3List = new List<DeptBaseResponseDomain>();
+
+                                if (rsplistsub3.Result != null)
+                                {
+                                    foreach (var dept3List in rsplistsub3.Result)
+                                    {
+                                        //添加三级部门
+                                        DeptBaseResponseDomain deptBaseResponseDomain3 = new DeptBaseResponseDomain();
+                                        deptBaseResponseDomain3.deptId = dept3List.DeptId;
+                                        deptBaseResponseDomain3.Name = dept3List.Name;
+                                        deptBaseResponseDomain3.ParentId = dept3List.ParentId;
+
+                                        //获取部门用户列表
+                                        OapiUserListidRequest reqUserList3 = new OapiUserListidRequest() { DeptId = dept3List.DeptId };
+                                        OapiUserListidResponse rspUserList3 = userListClient1.Execute(reqUserList3, access_token);
+                                        if (rspUserList3.Result != null)
+                                        {
+                                            //添加三级部门的用户
+                                            deptBaseResponseDomain3.ddUserList = rspUserList3.Result.UseridList;
+                                        }
+
+                                        //获取部门列表  四级目录
+                                        OapiV2DepartmentListsubRequest reqlistsub4 = new OapiV2DepartmentListsubRequest() { DeptId = dept3List.DeptId, Language = "zh_CN" };
+                                        OapiV2DepartmentListsubResponse rsplistsu4 = v2ListsubClient1.Execute(reqlistsub4, access_token);
+
+                                        List<DeptBaseResponseDomain> deptBaseResponseDomain4List = new List<DeptBaseResponseDomain>();
+                                        if (rsplistsu4.Result != null)
+                                        {
+
+                                            foreach (var dept4List in rsplistsu4.Result)
+                                            {
+                                                DeptBaseResponseDomain deptBaseResponseDomain4 = new DeptBaseResponseDomain();
+                                                deptBaseResponseDomain4.deptId = dept4List.DeptId;
+                                                deptBaseResponseDomain4.Name = dept4List.Name;
+                                                deptBaseResponseDomain4.ParentId = dept4List.ParentId;
+                                                deptBaseResponseDomain4List.Add(deptBaseResponseDomain4);
+
+                                                //获取三级部门用户列表
+                                                OapiUserListidRequest reqUserList4 = new OapiUserListidRequest() { DeptId = dept4List.DeptId };
+                                                OapiUserListidResponse rspUserList4 = userListClient1.Execute(reqUserList4, access_token);
+                                                if (rspUserList4.Result != null)
+                                                {
+                                                    //添加四级部门的用户
+                                                    deptBaseResponseDomain4.ddUserList = rspUserList4.Result.UseridList;
+                                                }
+                                            }
+                                        }
+                                        //添加四级部门列表
+                                        deptBaseResponseDomain3.LowerDeip_List = deptBaseResponseDomain4List;
+                                        deptBaseResponseDomain3List.Add(deptBaseResponseDomain3);
+                                    }
+                                }
+                                //添加三级部门列表
+                                deptBaseResponseDomain2.LowerDeip_List = deptBaseResponseDomain3List;
+                                deptBaseResponseDomainList.Add(deptBaseResponseDomain2);
+                            }
+                        }
+                        //添加二级部门列表
+                        deptInfo.deptList = deptBaseResponseDomainList;
+                        templsit.Add(deptInfo);
+                    }
+                }
+                return Ok(new { state = 200, deptlist = templsit });
+            }
+            catch (Exception ex)
+            {
+                return Ok(new { state = 1, message=$"查询失败!:状态:{ex.StackTrace}错误:{ex.Message}" }) ;
+            }
+        }
+
+        /// <summary>
+        /// 获取当前用户的父级集合
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("get-parentdept")]
+        public async Task<IActionResult> GetParentDept(JsonElement jsonElement) 
+        {
+            try
+            {
+                if (!jsonElement.TryGetProperty("userId", out JsonElement userId)) return Ok(new { state = 1, message = "参数错误!" });
+
+                string appKey = _configuration["DingDingAuth:appKey"];
+                string appSecret = _configuration["DingDingAuth:appSecret"];
+
+                //获取access_token
+                DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
+                OapiGettokenRequest request = new OapiGettokenRequest();
+                request.Appkey = appKey;
+                request.Appsecret = appSecret;
+                request.SetHttpMethod("Get");
+                OapiGettokenResponse response = client.Execute(request);
+                if (response.IsError)
+                {
+                    return BadRequest();
+                }
+
+                //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
+                string access_token = response.AccessToken; 
+
+                IDingTalkClient v2DeartDeptClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listparentbyuser");
+                OapiV2DepartmentListparentbyuserRequest reqDeartDept = new OapiV2DepartmentListparentbyuserRequest() { Userid = userId.ToString() };
+                OapiV2DepartmentListparentbyuserResponse rspDeartDept = v2DeartDeptClient.Execute(reqDeartDept, access_token);
+
+                if (rspDeartDept.Result != null)
+                {
+                    List<long> userParentDept = new List<long>();
+                    //var parentDept = rspDeartDept.Result.ParentList;
+                    foreach (var temp in rspDeartDept.Result.ParentList)
+                    {
+                        foreach (var deptTemp in temp.ParentDeptIdList)
+                        {
+                            userParentDept.Add(deptTemp);
+                        }
+                    }
+
+                    return Ok(new { state = 200, parentList = userParentDept });
+                }
+
+                return Ok(new { state = 2, message = "访问失败!" });
+            }
+            catch (Exception ex)
+            {
+                return Ok(new { state = 2, message = $"访问失败!状态:{ex.StackTrace} 错误:{ex.Message}" });
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <returns></returns>
+        public async Task<IActionResult> SetDeptList(JsonElement jsonElement) 
+        {
+            try
+            {
+                string appKey = _configuration["DingDingAuth:appKey"];
+                string appSecret = _configuration["DingDingAuth:appSecret"];
+
+                //获取access_token
+                DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
+                OapiGettokenRequest request = new OapiGettokenRequest();
+                request.Appkey = appKey;
+                request.Appsecret = appSecret;
+                request.SetHttpMethod("Get");
+                OapiGettokenResponse response = client.Execute(request);
+                if (response.IsError)
+                {
+                    return BadRequest();
+                }
+
+                //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
+                string access_token = response.AccessToken;
+
+                //获取部门列表 一级目录
+                IDingTalkClient v2ListsubClient1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
+                OapiV2DepartmentListsubRequest reqlistsub1 = new OapiV2DepartmentListsubRequest() { DeptId = 1L, Language = "zh_CN" };
+                OapiV2DepartmentListsubResponse rsplistsub1 = v2ListsubClient1.Execute(reqlistsub1, access_token);
+                List<DeptInfo> templsit = new List<DeptInfo>();
+
+                if (rsplistsub1.Result != null)
+                {
+                    foreach (var deptList in rsplistsub1.Result)
+                    {
+                        DeptInfo deptInfo = new DeptInfo();
+                        deptInfo.deptId = deptList.DeptId;
+                        deptInfo.deptName = deptList.Name;
+                        deptInfo.parentId = deptList.ParentId;
+
+                        //获取一级部门用户列表
+                        IDingTalkClient userListClient1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
+                        OapiUserListidRequest reqUserList1 = new OapiUserListidRequest() { DeptId = deptList.DeptId };
+                        OapiUserListidResponse rspUserList1 = userListClient1.Execute(reqUserList1, access_token);
+                        if (rspUserList1.Result != null)
+                        {
+                            deptInfo.ddUserList = rspUserList1.Result.UseridList;
+                        }
+
+                        //获取用户详细信息
+                        IDingTalkClient v2UserListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
+                        OapiV2UserGetRequest reqv2UserList = new OapiV2UserGetRequest();
+                        OapiV2UserGetResponse rspv2UserList = v2UserListClient.Execute(reqv2UserList, access_token);
+
+                        //获取二级部门列表
+                        OapiV2DepartmentListsubRequest reqlistsub = new OapiV2DepartmentListsubRequest() { DeptId = deptList.DeptId, Language = "zh_CN" };
+                        OapiV2DepartmentListsubResponse rsplistsub = v2ListsubClient1.Execute(reqlistsub, access_token);
+
+                        List<DeptBaseResponseDomain> deptBaseResponseDomainList = new List<DeptBaseResponseDomain>();
+                        if (rsplistsub.Result != null)
+                        {
+                            foreach (var deptlist2 in rsplistsub.Result)
+                            {
+                                //添加二级部门
+                                DeptBaseResponseDomain deptBaseResponseDomain2 = new DeptBaseResponseDomain();
+                                deptBaseResponseDomain2.deptId = deptlist2.DeptId;
+                                deptBaseResponseDomain2.Name = deptlist2.Name;
+                                deptBaseResponseDomain2.ParentId = deptlist2.ParentId;
+
+                                //获取三级部门用户列表
+                                OapiUserListidRequest reqUserList2 = new OapiUserListidRequest() { DeptId = deptlist2.DeptId };
+                                OapiUserListidResponse rspUserList2 = userListClient1.Execute(reqUserList2, access_token);
+                                if (rspUserList2.Result != null)
+                                {
+                                    //添加三级部门用户
+                                    deptBaseResponseDomain2.ddUserList = rspUserList2.Result.UseridList;
+                                }
+                                //获取三级部门列表
+                                OapiV2DepartmentListsubRequest reqlistsub3 = new OapiV2DepartmentListsubRequest() { DeptId = deptlist2.DeptId, Language = "zh_CN" };
+                                OapiV2DepartmentListsubResponse rsplistsub3 = v2ListsubClient1.Execute(reqlistsub3, access_token);
+
+                                List<DeptBaseResponseDomain> deptBaseResponseDomain3List = new List<DeptBaseResponseDomain>();
+
+                                if (rsplistsub3.Result != null)
+                                {
+                                    foreach (var dept3List in rsplistsub3.Result)
+                                    {
+                                        //添加三级部门
+                                        DeptBaseResponseDomain deptBaseResponseDomain3 = new DeptBaseResponseDomain();
+                                        deptBaseResponseDomain3.deptId = dept3List.DeptId;
+                                        deptBaseResponseDomain3.Name = dept3List.Name;
+                                        deptBaseResponseDomain3.ParentId = dept3List.ParentId;
+
+                                        //获取部门用户列表
+                                        OapiUserListidRequest reqUserList3 = new OapiUserListidRequest() { DeptId = dept3List.DeptId };
+                                        OapiUserListidResponse rspUserList3 = userListClient1.Execute(reqUserList3, access_token);
+                                        if (rspUserList3.Result != null)
+                                        {
+                                            //添加三级部门的用户
+                                            deptBaseResponseDomain3.ddUserList = rspUserList3.Result.UseridList;
+                                        }
+
+                                        //获取部门列表  四级目录
+                                        OapiV2DepartmentListsubRequest reqlistsub4 = new OapiV2DepartmentListsubRequest() { DeptId = dept3List.DeptId, Language = "zh_CN" };
+                                        OapiV2DepartmentListsubResponse rsplistsu4 = v2ListsubClient1.Execute(reqlistsub4, access_token);
+
+                                        List<DeptBaseResponseDomain> deptBaseResponseDomain4List = new List<DeptBaseResponseDomain>();
+                                        if (rsplistsu4.Result != null)
+                                        {
+
+                                            foreach (var dept4List in rsplistsu4.Result)
+                                            {
+                                                DeptBaseResponseDomain deptBaseResponseDomain4 = new DeptBaseResponseDomain();
+                                                deptBaseResponseDomain4.deptId = dept4List.DeptId;
+                                                deptBaseResponseDomain4.Name = dept4List.Name;
+                                                deptBaseResponseDomain4.ParentId = dept4List.ParentId;
+                                                deptBaseResponseDomain4List.Add(deptBaseResponseDomain4);
+
+                                                //获取三级部门用户列表
+                                                OapiUserListidRequest reqUserList4 = new OapiUserListidRequest() { DeptId = dept4List.DeptId };
+                                                OapiUserListidResponse rspUserList4 = userListClient1.Execute(reqUserList4, access_token);
+                                                if (rspUserList4.Result != null)
+                                                {
+                                                    //添加四级部门的用户
+                                                    deptBaseResponseDomain4.ddUserList = rspUserList4.Result.UseridList;
+                                                }
+                                            }
+                                        }
+                                        //添加四级部门列表
+                                        deptBaseResponseDomain3.LowerDeip_List = deptBaseResponseDomain4List;
+                                        deptBaseResponseDomain3List.Add(deptBaseResponseDomain3);
+                                    }
+                                }
+                                //添加三级部门列表
+                                deptBaseResponseDomain2.LowerDeip_List = deptBaseResponseDomain3List;
+                                deptBaseResponseDomainList.Add(deptBaseResponseDomain2);
+                            }
+                        }
+                        //添加二级部门列表
+                        deptInfo.deptList = deptBaseResponseDomainList;
+                        templsit.Add(deptInfo);
+                    }
+                }
+                return Ok(new { state = 200, deptlist = templsit });
+            }
+            catch (Exception ex)
+            {
+                return Ok(new { state = 1, message = $"查询失败!:状态:{ex.StackTrace}错误:{ex.Message}" });
+            }
+        }
+
+
+
+
+
+        public record DeptInfo 
+        {
+            /// <summary>
+            /// 部门ID
+            /// </summary>
+            public long deptId { get; set; }
+
+            /// <summary>
+            /// 部门名称
+            /// </summary>
+            public string deptName { get; set; }
+
+            /// <summary>
+            /// 父部门id,根部门为1
+            /// </summary>
+            public long parentId { get; set; }
+
+            /// <summary>
+            /// 部门集合
+            /// </summary>
+            public List<DeptBaseResponseDomain> deptList { get; set; }
+
+            /// <summary>
+            /// 钉钉用户列表
+            /// </summary>
+            public List<string> ddUserList { get; set; }
+
+
+        }
+
+        public record DeptBaseResponseDomain 
+        {
+            /// <summary>
+            /// 部门ID
+            /// </summary>
+            public long deptId { get; set; }
+
+            /// <summary>
+            /// 部门名称
+            /// </summary>
+            public string Name { get; set; }
+
+            /// <summary>
+            /// 父部门ID
+            /// </summary>
+            public long ParentId { get; set; }
+
+            /// <summary>
+            /// 下级列表
+            /// </summary>
+            public List<DeptBaseResponseDomain> LowerDeip_List { get; set; }
+
+            /// <summary>
+            /// 钉钉用户列表
+            /// </summary>
+            public List<string> ddUserList { get; set; }
+
+        }
+
+    }
+}

+ 1 - 1
TEAMModeBI/Controllers/LoginController.cs

@@ -324,7 +324,7 @@ namespace TEAMModeBI.Controllers
                         var ddbind = teacher.ddbinds.Find(x => x.userid.Equals($"{dingDingBind.userid}") && x.unionid.Equals($"{dingDingBind.unionid}"));
                         if (ddbind != null)
                         {
-                            return Ok(new { status = 200, id_token = implicit_token.id_token, access_token = implicit_token.access_token, expires_in = implicit_token.expires_in, token_type = implicit_token.token_type });
+                            return Ok(new { status = 200, teacher = teacher, id_token = implicit_token.id_token, access_token = implicit_token.access_token, expires_in = implicit_token.expires_in, token_type = implicit_token.token_type });
                         }
                     }
                     return Ok(new { status = 1, dingdinginfo = dingDingBind });

+ 3 - 3
TEAMModelFunction/TriggerExam.cs

@@ -710,13 +710,13 @@ namespace TEAMModelFunction
                 int phcount = 0;
                 int plcount = 0;
                 //存放并去重知识点
-                List<int> knowledgeName = new List<int>();
-                knowledgeName.Add(1);
+                List<int> knowledgeName = new List<int>() { 1,2,3,4,5,6};
+/*                knowledgeName.Add(1);
                 knowledgeName.Add(2);
                 knowledgeName.Add(3);
                 knowledgeName.Add(4);
                 knowledgeName.Add(5);
-                knowledgeName.Add(6);
+                knowledgeName.Add(6);*/
                 foreach (ExamClassResult classResult in classResults)
                 {
                     if (classResult.subjectId.Equals(subject.id))

+ 41 - 0
TEAMModelOS.SDK/Models/Cosmos/BI/DeptNode.cs

@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace TEAMModelOS.SDK.Models.Cosmos.BI
+{
+    /// <summary>
+    /// 所有部门信息
+    /// </summary>
+    public class DeptNode: CosmosEntity
+    {
+        public List<DeptInfo> depts { get; set; }
+    }
+
+    /// <summary>
+    /// 单个部门信息
+    /// </summary>
+    public class DeptInfo
+    {
+
+        [Required(ErrorMessage = "{0} 必须填写")]
+        public long id { get; set; }
+
+        /// <summary>
+        /// 父级
+        /// </summary>
+        [Required(ErrorMessage = "{0} 必须填写")]
+        public long pid { get; set; }
+
+        /// <summary>
+        /// 部门名称
+        /// </summary>
+        public string name { get; set; }
+
+        /// <summary>
+        /// 用户列表
+        /// </summary>
+        public List<string> users { get; set; }
+    }
+}

+ 26 - 7
TEAMModelOS.SDK/Models/Cosmos/Common/SheetConfig.cs

@@ -90,18 +90,37 @@ namespace TEAMModelOS.SDK.Models
         /// </summary>
         public List<ConfigContent> contents { get; set; }
     }
+    //public class ConfigContent
+    //{
+    //    public int index { get; set; }
+    //    public int count { get; set; }
+    //    public int type { get; set; }
+    //    public int x { get; set; }
+    //    public int y { get; set; }
+    //    public int width { get; set; }
+    //    public int height { get; set; }
+    //    public int pageNum { get; set; }
+    //    public int vblockCount { get; set; }
+    //    public int hblockCount { get; set; }
+    //    public int id { get; set; }        
+    //}
     public class ConfigContent
     {
         public int index { get; set; }
         public int count { get; set; }
         public int type { get; set; }
-        public int x { get; set; }
-        public int y { get; set; }
-        public int width { get; set; }
-        public int height { get; set; }
         public int pageNum { get; set; }
-        public int vblockCount { get; set; }
-        public int hblockCount { get; set; }
-        public int id { get; set; }        
+        public List<Pos> pos { get; set; } = new List<Pos>();
+        public List<Point> points { get; set; } = new List<Point>();
+    }
+    public  class Pos
+    {
+        public double x { get; set; }
+        public double y { get; set; }
+    }
+    public class Point { 
+        public string ans { get; set; }
+        public int row { get; set; }
+        public List<Pos> pos { get; set; } = new List<Pos>();
     }
 }

+ 1 - 1
TEAMModelOS.SDK/Models/Service/GroupListService.cs

@@ -546,7 +546,7 @@ namespace TEAMModelOS.SDK.Models.Service
                 foreach (MQActivity activity in datas)
                 {
                     //已经完结的不再允许加入,还未开始的。
-                    if (activity.progress.Equals("finish") || activity.progress.Equals("pending"))
+                    if (string.IsNullOrEmpty(activity.progress)|| activity.progress.Equals("finish") || activity.progress.Equals("pending"))
                     {
                         continue;
                     }

+ 1 - 1
TEAMModelOS.SDK/Models/Service/StuListService.cs

@@ -63,7 +63,7 @@ namespace TEAMModelFunction
                 foreach (MQActivity activity in datas)
                 {
                     //已经完结的不再允许加入
-                    if (activity.progress.Equals("finish") || activity.progress.Equals("pending"))
+                    if (string.IsNullOrEmpty(activity.progress)|| activity.progress.Equals("finish") || activity.progress.Equals("pending"))
                     {
                         continue;
                     }

+ 49 - 3
TEAMModelOS/ClientApp/src/assets/iconfont/demo_index.html

@@ -54,6 +54,18 @@
       <div class="content unicode" style="display: block;">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+              <span class="icon iconfont">&#xe6dd;</span>
+                <div class="name">展开</div>
+                <div class="code-name">&amp;#xe6dd;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe664;</span>
+                <div class="name">收起</div>
+                <div class="code-name">&amp;#xe664;</div>
+              </li>
+          
             <li class="dib">
               <span class="icon iconfont">&#xe656;</span>
                 <div class="name">橡皮擦</div>
@@ -942,9 +954,9 @@
 <pre><code class="language-css"
 >@font-face {
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1634804027474') format('woff2'),
-       url('iconfont.woff?t=1634804027474') format('woff'),
-       url('iconfont.ttf?t=1634804027474') format('truetype');
+  src: url('iconfont.woff2?t=1636356086567') format('woff2'),
+       url('iconfont.woff?t=1636356086567') format('woff'),
+       url('iconfont.ttf?t=1636356086567') format('truetype');
 }
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -970,6 +982,24 @@
       <div class="content font-class">
         <ul class="icon_lists dib-box">
           
+          <li class="dib">
+            <span class="icon iconfont icon-zhankai"></span>
+            <div class="name">
+              展开
+            </div>
+            <div class="code-name">.icon-zhankai
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-shouqi"></span>
+            <div class="name">
+              收起
+            </div>
+            <div class="code-name">.icon-shouqi
+            </div>
+          </li>
+          
           <li class="dib">
             <span class="icon iconfont icon-eraser1"></span>
             <div class="name">
@@ -2302,6 +2332,22 @@
       <div class="content symbol">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-zhankai"></use>
+                </svg>
+                <div class="name">展开</div>
+                <div class="code-name">#icon-zhankai</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shouqi"></use>
+                </svg>
+                <div class="name">收起</div>
+                <div class="code-name">#icon-shouqi</div>
+            </li>
+          
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#icon-eraser1"></use>

+ 11 - 3
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 2000444 */
-  src: url('iconfont.woff2?t=1634804027474') format('woff2'),
-       url('iconfont.woff?t=1634804027474') format('woff'),
-       url('iconfont.ttf?t=1634804027474') format('truetype');
+  src: url('iconfont.woff2?t=1636356086567') format('woff2'),
+       url('iconfont.woff?t=1636356086567') format('woff'),
+       url('iconfont.ttf?t=1636356086567') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,14 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-zhankai:before {
+  content: "\e6dd";
+}
+
+.icon-shouqi:before {
+  content: "\e664";
+}
+
 .icon-eraser1:before {
   content: "\e656";
 }

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.js


+ 14 - 0
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.json

@@ -5,6 +5,20 @@
   "css_prefix_text": "icon-",
   "description": "",
   "glyphs": [
+    {
+      "icon_id": "680107",
+      "name": "展开",
+      "font_class": "zhankai",
+      "unicode": "e6dd",
+      "unicode_decimal": 59101
+    },
+    {
+      "icon_id": "1760316",
+      "name": "收起",
+      "font_class": "shouqi",
+      "unicode": "e664",
+      "unicode_decimal": 58980
+    },
     {
       "icon_id": "5060936",
       "name": "橡皮擦",

BIN
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.ttf


BIN
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.woff


BIN
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.woff2


+ 12 - 4
TEAMModelOS/ClientApp/src/assets/student-web/component_styles/event-list.less

@@ -53,23 +53,31 @@
                 color: white;
             }
 
+            & > p {
+                text-align: center;
+                font-size: 13px;
+            }
+
             .innerIcon {
                 width: 24px;
                 height: 24px;
                 position: relative;
             }
-            .Icon-0,
+            .Icon-0{
+                top: 12px;
+                left: 12px;
+            }
             .Icon-1,
             .Icon-4 {
-                top: 12px;
+                top: 6px;
                 left: 12px;
             }
             .Icon-2 {
-                top: 13px;
+                top: 6px;
                 left: 15px;
             }
             .Icon-3,.Icon-5  {
-                top: 12px;
+                top: 6px;
                 left: 13px;
             }
           

+ 2 - 0
TEAMModelOS/ClientApp/src/boot-app.js

@@ -109,6 +109,8 @@ Vue.prototype._ = _
 // Registration of global components
 Vue.component('icon', FontAwesomeIcon)
 
+store.dispatch('config/checkSrvAdr');// 檢查現在站的位置
+
 router.beforeEach((to, from, next) => {
     document.body.scrollTop = 0
     next()

+ 2 - 2
TEAMModelOS/ClientApp/src/common/BaseSelectSchool.vue

@@ -177,8 +177,8 @@
 						this.$EventBus.$emit('onGlobalLoading', false)
 					}, 1500)
 					routerInfo = routerInfo || { name: 'homePage' }
-					console.error(routerInfo.name);
-					console.error(this.$route);
+					// console.error(routerInfo.name);
+					// console.error(this.$route);
 					this.$router.push(routerInfo)
 					if(routerInfo.name === this.$route.name){
 						this.reload()

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

@@ -43,7 +43,7 @@
         height: 100%;
         display: flex;
         flex-direction: column;
-        justify-content: center;
+        /* justify-content: center; */
         align-items: center;
     }
 

+ 5 - 3
TEAMModelOS/ClientApp/src/common/HtexRender.vue

@@ -33,6 +33,8 @@ export default {
     },
     data() {
         return {
+            stageWidth:810,
+            stageHeight:450,
             stage: '',
             layersinfo: '',
             renderData: {
@@ -53,14 +55,14 @@ export default {
             page === 0 ? (pagenow = page) : (pagenow = page - 1);
             return new Promise(async (r, j) => {
                 // var scaling =(window.innerHeight / res.height).toFixed(2) &&res.height !== ""? (window.innerHeight / res.height).toFixed(2): 0;
-                var scaling = 1280 / jsonUrl.width
+                var scaling = this.stageWidth / jsonUrl.width
                 console.log('缩放比例', scaling)
                 var stageX = (window.innerWidth - jsonUrl.width * scaling) / 2 && jsonUrl.width !== "" ? (window.innerWidth - jsonUrl.width * scaling) / 2 : 0;
                 var callUrl = urlHost;
                 var stage = new Konva.Stage({
                     container: "container",
-                    width: 1280,
-                    height: 720,
+                    width: this.stageWidth,
+                    height: this.stageHeight,
                     scale: scaling,
                     x: 0,
                     y: 0,

+ 34 - 8
TEAMModelOS/ClientApp/src/common/MyHTEXRender.vue

@@ -1,8 +1,8 @@
 <template>
     <div class="htex-render-wrap">
         <HTEXRender :renderJson="curPageData"></HTEXRender>
-        <div class="page-wrap">
-            <Page v-if="indexData.slides" :total="indexData.slides.length" :page-size="1" size="small" @on-change="toPage"/>
+        <div :class="isInner ? 'page-wrap-inner' : 'page-wrap'">
+            <Page v-if="indexData.slides" :total="indexData.slides.length" :current="curPage" :page-size="1" size="small" @on-change="toPage" />
             <!-- <Icon type="md-expand" class="full-screen" @click="fullScreen"/> -->
         </div>
     </div>
@@ -18,6 +18,15 @@ export default {
             type: String,
             default: '',
             required: true
+        },
+        //换页是否内部显示
+        isInner: {
+            type: Boolean,
+            default: false
+        },
+        page: {
+            type: Number,
+            default: 1
         }
     },
     data() {
@@ -33,12 +42,13 @@ export default {
         }
     },
     methods: {
-        fullScreen(){
+        fullScreen() {
             this.$Message.warning('全屏功能开发中')
         },
-        toPage(page){
+        toPage(page) {
             console.log(page)
             this.renderPage(page)
+            this.$emit('onPageChange', page)
         },
         /**
          * @param page 页码 index = page - 1 
@@ -91,22 +101,38 @@ export default {
                 }
             },
             immediate: true
+        },
+        page: {
+            handler(n, o) {
+                this.renderPage(n)
+            }
         }
     }
 }
 </script>
 <style lang="less" scoped>
-.htex-render-wrap{
+.htex-render-wrap {
+    position: relative;
     width: fit-content;
     background: rgba(255, 255, 255, 1);
 }
-.page-wrap{
+.page-wrap {
+    width: 100%;
+    height: fit-content;
+    background: rgba(81, 90, 110, 0.8);
+    padding: 8px 4px;
+    text-align: center;
+}
+.page-wrap-inner {
     width: 100%;
     height: fit-content;
-    background: rgba(81, 90, 110, .8);
+    background: rgba(81, 90, 110, 0.7);
     padding: 8px 4px;
+    position: absolute;
+    bottom: 0px;
+    text-align: center;
 }
-.full-screen{
+.full-screen {
     float: right;
     color: white;
     margin-top: -18px;

+ 6 - 1
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.less

@@ -217,7 +217,7 @@
     padding: 0 10px;
     height: 26px;
     color: white;
-    margin-right: 25px;
+    margin-right: 10px;
     font-weight: bolder;
     float: right;
 }
@@ -302,6 +302,11 @@
     cursor: pointer;
 }
 
+.ansDetail.iconfont{
+    font-size: 26px !important;
+    font-weight: bolder;
+}
+
 .closeAnsDetail {
     float: right;
     height: 28px;

+ 6 - 2
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue

@@ -90,8 +90,12 @@
                         {{$t("studentWeb.exam.report.noScore")}}: {{rightAns.noAns}}
                     </Checkbox>
                 </CheckboxGroup>
-                <span @click="closeDetail">
-                    <svg-icon icon-class="AnsWerDetail" :class="{ ansDetail: !closeAnsDetail, closeAnsDetail: closeAnsDetail,}" />
+                <span v-show="closeAnsDetail" @click="closeDetail">
+                    <Icon custom="iconfont icon-zhankai" class="ansDetail" :title="$t('studentWeb.exam.report.openExam')" />
+                    <!-- <svg-icon icon-class="AnsWerDetail" :class="{ ansDetail: !closeAnsDetail, closeAnsDetail: closeAnsDetail,}" /> -->
+                </span>
+                <span v-show="!closeAnsDetail" @click="closeDetail">
+                    <Icon custom="iconfont icon-shouqi" class="ansDetail" :title="$t('studentWeb.exam.report.closeExam')" />
                 </span>
                 <button :class="['wrong-exercises', rightAns.wrong != 0 ? 'wrong' : 'nowrong']" @click="showTest">
                     {{$t("studentWeb.exam.report.wrongPractice")}}

+ 2 - 2
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReportCharts/KeyPointPerformChart.vue

@@ -129,8 +129,8 @@ export default {
         },
     },
     mounted() {
-        // this.getknowledge()
-        // this.setMap()
+        this.getknowledge()
+        this.setMap()
     },
     watch: {
         knowledge: {

+ 2 - 2
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReportCharts/RecognizePerformChart.vue

@@ -103,8 +103,8 @@ export default {
         },
     },
     mounted() {
-        // this.getFiled()
-        // this.setMap()
+        this.getFiled()
+        this.setMap()
     },
     watch: {
         filed: {

+ 1 - 1
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.vue

@@ -30,7 +30,7 @@
                                 <svg-icon icon-class="test" class="title-icon" />
                                 <span style="margin-top:5px">{{ item.subject.name }}{{getItemTitle.scope == 'school' ? $t('studentWeb.exam.isSubject'):''}}</span>
                                 <div v-show="item.stuAns != undefined">
-                                    <div :class="{ unfinished: item.stuAns.length == 0 ,finished:item.stuAns.length != 0 }">
+                                    <div :class="{ unfinished: item.stuAns.length === 0 ,finished: item.stuAns.length != 0 }">
                                         <Icon style="margin-top: -10px; margin-left: -8px;" type="ios-checkmark" size="36" />
                                     </div>
                                 </div>

+ 4 - 3
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue

@@ -51,6 +51,7 @@
                                       class="innerIcon"
                                       :class="`Icon-${index + 1}`" 
                             />
+                            <p>{{ iconBtn.title }}</p>
                             <div class="dev-top" v-if="iconBtn.eventType == 'Preview'">
                                 <span class="develop">{{ $t("studentWeb.public.develop") }}</span>
                             </div>
@@ -267,7 +268,7 @@ import { mapGetters, mapState } from 'vuex';
         computed: {
             ...mapState({
                 studentProfile: state => state.user.studentProfile,
-                schoolCode: state => state.user.schoolCode,
+                // schoolCode: state => state.user.schoolCode,
                 userInfo: state => state.userInfo,
             }),
             ...mapGetters([
@@ -292,7 +293,7 @@ import { mapGetters, mapState } from 'vuex';
                     params = {
                         userid: this.userInfo.sub,
                         userType: "tmdid",
-                        school: this.schoolCode
+                        school: this.userInfo.azp
                     }
                 }
                 // 学生账号登陆
@@ -300,7 +301,7 @@ import { mapGetters, mapState } from 'vuex';
                     params = {
                         userid: this.userInfo.sub,
                         userType: "schoolid",
-                        school: this.schoolCode
+                        school: this.userInfo.azp
                     }
                     
                 }

+ 3 - 3
TEAMModelOS/ClientApp/src/components/student-web/HomeView/HomeView.vue

@@ -157,8 +157,8 @@
                                             {{ item.name }}
                                             <p>{{ item.teaName }}</p>
                                         </div>
-                                        <p class="time">上课时间:{{ item.classTime }}</p>
-                                        <p class="place">上课教室:{{ item.roomName }}</p>
+                                        <p class="time">{{ $t("studentWeb.baseInfo.classTime") }}:{{ item.classTime }}</p>
+                                        <p class="place">{{ $t("studentWeb.courseContent.classroom") }}:{{ item.roomName }}</p>
                                     </div>
                                 </div>
                                 <div v-else class="no-data">{{ $t("studentWeb.public.noData") }}</div>
@@ -348,7 +348,7 @@ export default {
             let params = {
                 userid: this.userInfo.sub,
                 userType: "",
-                school: this.user.schoolCode
+                school: this.userInfo.azp
             }
             // 醍摩豆登陆——> roles有teacher
             if (this.userInfo.scope === "tmduser") {

+ 5 - 5
TEAMModelOS/ClientApp/src/components/student-web/HomeView/newHomeView.vue

@@ -63,8 +63,8 @@
                                             {{ item.name }}
                                             <p>{{ item.teaName }}</p>
                                         </div>
-                                        <p class="time">上课时间:{{ item.classTime }}</p>
-                                        <p class="place">上课教室:{{ item.roomName }}</p>
+                                        <p class="time">{{ $t("studentWeb.baseInfo.classTime") }}:{{ item.classTime }}</p>
+                                        <p class="place">{{ $t("studentWeb.courseContent.classroom") }}:{{ item.roomName }}</p>
                                     </div>
                                 </div>
                                 <div v-else class="no-data">{{ $t("studentWeb.public.noData") }}</div>
@@ -259,7 +259,7 @@ export default {
             let params = {
                 userid: this.userInfo.sub,
                 userType: "",
-                school: this.user.schoolCode
+                school: this.userInfo.azp
             }
             // 醍摩豆登陆——> roles有teacher
             if (this.userInfo.scope === "tmduser") {
@@ -622,7 +622,7 @@ export default {
         }
     }
 
-    .calenderCard {
+    // .calenderCard {
         /* .ivu-card-body {
             padding: 28px;
             padding-bottom: 0px;
@@ -635,7 +635,7 @@ export default {
                 padding-bottom: 0px;
             }
         } */
-    }
+    // }
 
     .addClass {
         .ivu-input-icon {

+ 48 - 35
TEAMModelOS/ClientApp/src/css/site.css

@@ -174,7 +174,7 @@ audio::-internal-media-controls-overflow-button {
 	vertical-align: middle;
 }
 
-.richText-audio audio{
+.richText-audio audio {
 	width: auto;
 }
 
@@ -248,7 +248,7 @@ audio::-internal-media-controls-overflow-button {
 	margin-top: 30px;
 }
 
-.related-modal .modal-btn:hover{
+.related-modal .modal-btn:hover {
 	background: #70B1E7 !important;
 	color: #fff;
 }
@@ -257,33 +257,33 @@ audio::-internal-media-controls-overflow-button {
 	height: 85%;
 }
 
-	.score-table-group-row{
-		background-color: #bebebe;
-		color: #fff;
-	}
-	
-	.score-table-group-row td{
-		background-color: transparent !important;
-		height: 45px !important;
-	}
-	
-	.score-table-compose-row{
-		background-color: #dfdfdf;
-	}
-	
-	.score-table-compose-row td{
-		background-color: transparent !important;
-		height: 45px !important;
-	}
-	
-	.score-table-row{
-		background-color: transparent;
-	}
-	
-	.score-table-row td{
-		background-color: transparent !important;
-		height: 45px !important;
-	}
+.score-table-group-row {
+	background-color: #bebebe;
+	color: #fff;
+}
+
+.score-table-group-row td {
+	background-color: transparent !important;
+	height: 45px !important;
+}
+
+.score-table-compose-row {
+	background-color: #dfdfdf;
+}
+
+.score-table-compose-row td {
+	background-color: transparent !important;
+	height: 45px !important;
+}
+
+.score-table-row {
+	background-color: transparent;
+}
+
+.score-table-row td {
+	background-color: transparent !important;
+	height: 45px !important;
+}
 
 /*横向垂直水平居中*/
 .flex-row-center {
@@ -302,8 +302,8 @@ audio::-internal-media-controls-overflow-button {
 }
 
 .base-table-row {
-  padding: 0 100px 0 55px;
-  margin-top: 50px;
+	padding: 0 100px 0 55px;
+	margin-top: 50px;
 }
 
 .component-title {
@@ -318,24 +318,37 @@ audio::-internal-media-controls-overflow-button {
 	background-color: var(--active-item-start);
 }
 
-.common-toolTip .ivu-tooltip-inner{
+.common-toolTip .ivu-tooltip-inner {
 	width: 200px;
 	word-break: break-word;
 }
 
-.common-toolTip .ivu-icon{
+.common-toolTip .ivu-icon {
 	vertical-align: middle !important;
 	color: #40A8F0;
 	margin: 0 5px !important;
 	font-size: 16px;
 }
 
-.w-e-text table td, .w-e-text table th{
+.w-e-text table td,
+.w-e-text table th {
 	height: 30px;
 }
 
-.text-cut{
+.text-cut {
 	text-overflow: ellipsis;
 	white-space: nowrap;
 	overflow: hidden;
 }
+dot{
+	position: relative;
+}
+dot::before {
+	position: absolute;
+	content: '';
+	width: 100%;
+	height: 4px;
+	bottom: -4px;
+	left: 0;
+	background: url('https://teammodelstorage.blob.core.chinacloudapi.cn/download/dot.png') repeat-x 0 center;
+}

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/en-US/evaluation.js

@@ -6,6 +6,7 @@ export default {
 	syncItems:'同步試題到題庫',
 	syncPoints:'保存時同步知識點到校本庫',
 	paperTag:'試卷標簽',
+	paperTagPlace:'選擇標簽或者手動輸入後回車創建新標簽',
 	useTip:'請至少保留一種試題用途',
 	editor:{
 		uploadVideo:'Upload Local Video',

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/en-US/jyzx.js

@@ -24,6 +24,7 @@ export default{
         success2: "舉報成功",
         success3: "刪除成功",
         error: "刪除失敗",
+        noData: '暫無數據',
     },
     // 线上研修
     online: {

+ 5 - 0
TEAMModelOS/ClientApp/src/locale/lang/en-US/stuAccount.js

@@ -66,6 +66,11 @@ export default {
   noMatch:'No matching data yet',
   stuIdErr:'Student account cannot be empty',
   stuIdErr1:'Student account can only contain numbers',
+  setNoErr:'學生座位號不能為空',
+  classErr:'請設置學生所在班級',
+  pwErr:'密碼不能為空',
+  nameErr:'學生姓名不能為空',
+  repeatErr:'賬號或座號重複了',
 
   // ImportStudent.vue
   importTitle: 'Import Student List',

+ 2 - 0
TEAMModelOS/ClientApp/src/locale/lang/en-US/studentWeb.js

@@ -457,6 +457,8 @@ export default {
             wrong: 'Answered Incorrectly',
             noScore: 'Not Graded',
             noAnswer: "Not Answered",
+            openExam: "展开试题",
+            closeExam: "收起试题",
             ansRes: 'Answering Result',
             mark: 'Annotate',
             testAns: 'Reference Answer',

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/evaluation.js

@@ -6,6 +6,7 @@ export default {
 	syncItems:'同步试题到题库',
 	syncPoints:'保存时同步知识点到校本库',
 	paperTag:'试卷标签',
+	paperTagPlace:'选择标签或者手动输入后回车创建新标签',
 	useTip:'请至少保留一种试题用途',
 	editor:{
 		uploadVideo:'上传本地视频',

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/jyzx.js

@@ -24,6 +24,7 @@ export default{
         success2: "举报成功",
         success3: "删除成功",
         error: "删除失败",
+        noData:'暂无数据',
     },
     // 线上研修
     online: {

+ 5 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/stuAccount.js

@@ -66,6 +66,11 @@ export default {
   noMatch: '暂无匹配数据',
   stuIdErr: '学生账号不能为空',
   stuIdErr1: '学生账号只能包含数字',
+  setNoErr:'学生座位号不能为空',
+  classErr:'请设置学生所在班级',
+  pwErr:'密码不能为空',
+  nameErr:'学生姓名不能为空',
+  repeatErr:'账号或座号重复了',
 
   // ImportStudent.vue
   importTitle: '导入学生名单',

+ 2 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/studentWeb.js

@@ -457,6 +457,8 @@ export default {
             wrong: '答错',
             noScore: '未评分',
             noAnswer: "未答题",
+            openExam: "展开试题",
+            closeExam: "收起试题",
             ansRes: '作答结果',
             mark: '批注',
             testAns: '参考答案',

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/evaluation.js

@@ -6,6 +6,7 @@ export default {
 	syncItems:'同步試題到題庫',
 	syncPoints:'保存時同步知識點到校本庫',
 	paperTag:'試卷標簽',
+	paperTagPlace:'選擇標簽或者手動輸入後回車創建新標簽',
 	useTip:'請至少保留一種試題用途',
 	editor: {
 		uploadVideo: '上傳本機影片',

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/jyzx.js

@@ -24,6 +24,7 @@ export default{
         success2: "舉報成功",
         success3: "刪除成功",
         error: "刪除失敗",
+        noData:'暫無數據',
     },
     // 线上研修
     online: {

+ 5 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/stuAccount.js

@@ -66,6 +66,11 @@ export default {
   noMatch:'暫無匹配數據',
   stuIdErr:'學生帳號不能為空',
   stuIdErr1:'學生帳號只能包含數字',
+  setNoErr:'學生座位號不能為空',
+  classErr:'請設置學生所在班級',
+  pwErr:'密碼不能為空',
+  nameErr:'學生姓名不能為空',
+  repeatErr:'賬號或座號重複了',
 
   //ImportStudent.vue
   importTitle: '匯入學生名單',

+ 2 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/studentWeb.js

@@ -457,6 +457,8 @@ export default {
             wrong: '答錯',
             noScore: '未評分',
             noAnswer: "未答題",
+            openExam: "展開試題",
+            closeExam: "收起試題",
             ansRes: '作答結果',
             mark: '批註',
             testAns: '參考答案',

+ 9 - 0
TEAMModelOS/ClientApp/src/router/routes.js

@@ -300,6 +300,15 @@ export const routes = [{
 					activeName: 'taskList'
 				}
 			},
+			// 批量按题阅卷
+			{
+				path: 'ByQu2',
+				name: 'ByQu2',
+				component: resolve => require(['@/view/task/mark/ByQu2.vue'], resolve),
+				meta: {
+					activeName: 'taskList'
+				}
+			},
 			// 仲裁阅卷页面
 			{
 				path: 'ArbView',

+ 44 - 11
TEAMModelOS/ClientApp/src/store/module/answerSheet.js

@@ -22,6 +22,7 @@ import {
 	NUMBER_ITEM_MT,
 	NUMBER_ITEM_ML
 } from '../../utils/sheetConfig'
+import $tools from '@/utils/public.js'
 export default {
 	state: {
 		count: 0,
@@ -77,22 +78,36 @@ export default {
 			"pageNumStartValue": 1, //页码起始值, 起始是3个空格方块开始,写1; 2个空格1个实心,写0
 			//内容块 vblockCount为该模块竖向的方块数 hblockCount为该模块横向方块数
 			"contents": [],
-			"infoMode":'number',
-			"infoPos":[],
-			"objectivePos":[],
+			"newContents":[],
 			"mode":"A4"
 		}
 	},
 
 	mutations: {
-		setInfoMode(state, val) {
-			state.config.infoMode = val
+		/* 添加信息框数据 */
+		addInfoContent(state,val){
+			state.config.newContents = state.config.newContents.filter(i => i.type !== 0 && i.type !== 1)
+			state.config.newContents.push(val)
 		},
-		setInfoPos(state, val) {
-			state.config.infoPos = val
+		
+		/* 添加客观题框数据 */
+		addObjectiveContent(state,val){
+			let objectiveConfig = state.config.newContents.findIndex(i => i.type === 2)
+			if(objectiveConfig > -1){
+				state.config.newContents.splice(objectiveConfig,1,val)
+			}else{
+				state.config.newContents.push(val)
+			}
+		},
+		
+		/* 添加填空题数据 */
+		addCompleteContent(state,val){
+			state.config.newContents.push(val)
 		},
-		setObjectivePos(state, val) {
-			state.config.objectivePos = val
+		
+		/* 添加简答题数据 */
+		addSubjectiveContent(state,val){
+			state.config.newContents.push(val)
 		},
 		setCreateModal(state, val) {
 			state.isAutoCreate = val === 'auto'
@@ -155,13 +170,14 @@ export default {
 			}
 		},
 		setSubjectiveConfig(state,val){
+			// console.error('setSubjectiveConfig',val.startOrder,val.type,state.config.newContents[state.config.newContents.length - 1].type)
 			let index = state.config.contents.filter(i => i.pageNum === val.pageNum).length + 1
 			val.x = Number(val.x.toFixed())
 			val.y = Number(val.y.toFixed())
 			val.width = Number(val.width.toFixed())
 			val.height = Number(val.height.toFixed())
 			// ID为当前题目的第几个框
-			val.id = state.config.contents.filter(i => i.startOrder === val.startOrder).length + 1
+			val.id = state.config.contents.filter(i => i.startOrder === val.startOrder).length
 			// 如果是补充框 ID要保持和上一个ID一致
 			if(index === 1 && val.isFix){
 				let prePageItems = state.config.contents.filter(i => i.pageNum === val.pageNum - 1)
@@ -185,13 +201,29 @@ export default {
 				// delete val.startOrder
 				state.config.contents.push(val)
 			}
+			
+			/* 加入新的contents里面 */
+			let curTypeContentArr = state.config.newContents.filter(i => i.type ===  val.type)
+			let newContent = curTypeContentArr[curTypeContentArr.length - 1]
+			newContent.points.push({
+				ans:val.id,
+				row:val.startOrder,
+				pos:$tools.getBoxPos(val.x,val.y,val.width,val.height)
+			})
 		},
 		deleteItem(state, val) {
 			let index = state.paperItem.item.map(i => i.id).indexOf(val)
 			state.paperItem.item.splice(index, 1)
 		},
-		addPage(state) {
+		addPage(state,val) {
 			state.pages++
+			state.config.newContents.push({
+				"type": val,
+				"pageNum": state.pages,
+				"count": 0,
+				"pos": [],
+				"points": []
+			})
 		},
 		clearPage(state) {
 			 state.pages = 1
@@ -199,6 +231,7 @@ export default {
 		},
 		clearAllConfig(state){
 			state.config.contents = []
+			state.config.newContents = []
 		},
 		changeNewPage(state, val) {
 			state.isNewPage = val

+ 2 - 2
TEAMModelOS/ClientApp/src/utils/evTools.js

@@ -11,8 +11,8 @@ import { app } from '@/boot-app.js'
 
 export default {
 	/* 根据登录后的用户信息获取blobHOST域名 */
-	getBlobHost(){
-		let s = store.state.user.userProfile.blob_uri || store.state.user.studentProfile.blob_uri
+	getBlobHost(url){
+		let s = url || store.state.user.userProfile.blob_uri || store.state.user.studentProfile.blob_uri
 		let pattern = /[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/
 		return s.split('//')[0] + '//' + s.match(pattern)[0]
 	},

+ 129 - 22
TEAMModelOS/ClientApp/src/utils/html2pdf.js

@@ -2,11 +2,12 @@
 import JsPDF from 'jspdf'
 import store from '@/store'
 import domtoimage from './dom_to_image';
+import $tools from './public.js'
 export default {
 	install(Vue, options) {
-		Vue.prototype.getPdf = () => {
+		Vue.prototype.getPdf = (mode,sheetNo) => {
 			return new Promise((r, j) => {
-				var title = store.state.answerSheet.paperItem.name
+				var title = `${store.state.answerSheet.paperItem.name}-${sheetNo}(${mode})`
 				setTimeout(() => {
 					domtoimage.toJpeg(document.querySelector('#pdfDom'), {
 							bgcolor: '#fff'
@@ -19,6 +20,8 @@ export default {
 								console.log('width', img.width);
 								// const a4Height = 841.89
 								// const a4Width = 595.28
+								const a4HeightPx = 1165
+								const a4WidthPx = 826
 								const a4Height = 297
 								const a4Width = 210
 								let contentWidth = img.width
@@ -29,26 +32,128 @@ export default {
 								//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
 								let imgWidth = a4Width
 								let imgHeight = a4Width / contentWidth * contentHeight
+								
+								let mm2px = $tools.getOneMmsPx()
+								let xMarginMM = 15 / mm2px - 0.2
+								let yMarginMM = 40 / mm2px - 0.2
+								let pdfBorderHeight = a4Height - 22.7
 								// console.log(pageData)
-								let PDF = new JsPDF({
-									orientation: 'p',
-									unit: 'mm',
-									format: 'a4',
-									putOnlyUsedFonts: true
-								})
-								// 如果是一页的情况
-								if (leftHeight <= pageHeight) {
-									PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth,
-										imgHeight)
-								} else {
-									// 如果超出则多页
-									while (leftHeight > 0) {
-										PDF.addImage(pageData, 'JPEG', 0, position,
-											imgWidth, imgHeight)
-										leftHeight -= pageHeight
-										position -= a4Height
-										if (leftHeight > 0) {
-											PDF.addPage()
+								let PDF = null 
+								/* 分割长图 */
+								function segmentationImage(img, width, height) {
+								  let canvas = document.createElement("canvas");
+									canvas.width = width;
+									canvas.height = height;
+								  let ctx = canvas.getContext("2d");
+								  let imgList = [];
+								  let cropCount = Math.ceil(img.height / height);
+								  for(let num = 0; num < cropCount; num++) {
+									ctx.clearRect(0,0,canvas.width,canvas.height);
+									ctx.drawImage(img, 0, num * height, width, height, 0, 0, width, height);
+									imgList.push(canvas.toDataURL());
+								  }
+								  return imgList
+								}
+								/* 用JSPDF绘制每一页的外框页码和答题卡编号 */
+								function pdfDrawInfo(pageNo){
+									let curPage = mode === 'A4' ? pageNo : pageNo / 2
+									// 页码二进制框
+									let i = curPage.toString(2)
+									let radixArr = i.length === 1 ? '00' + i : i.length === 2 ? '0' + i : i
+									// 绘制锚点
+									for (let index = 0; index < 3; index++) {
+										if(radixArr.split('')[index] === '1'){
+											PDF.rect(xMarginMM + index * 10, a4Height - 7, 7, 3,'F');
+										}else{
+											PDF.rect(xMarginMM + index * 10, a4Height - 7, 7, 3);
+										}
+										
+									}
+									if(mode === 'A4'){
+										// 页面外框
+										PDF.rect(xMarginMM, yMarginMM ,a4Width - xMarginMM * 2,pdfBorderHeight)
+										// 页码
+										PDF.text(`${curPage} / ${totalPage}`, a4Width / 2 - 5, a4Height - 4,'center')
+										// 答题卡编号
+										PDF.text(`${sheetNo}`, a4Width - 20, a4Height - 4)
+									}else{
+										// 页面外框
+										PDF.rect(xMarginMM, yMarginMM ,a4Width * 2 - xMarginMM * 2,pdfBorderHeight);
+										// 页码
+										PDF.text(`${curPage} / ${ totalPage }`, a4Width, a4Height - 4,'center')
+										// 答题卡编号
+										PDF.text(`${sheetNo}`, a4Width * 2 - 20, a4Height - 4)
+									}
+									
+								}
+								// 获取分割的图片数量
+								let cropCount = Math.ceil(img.height / a4HeightPx);
+								if(cropCount === 0) return
+								let totalPage = mode === 'A4' ? cropCount : ( (cropCount % 2 === 0) ? (cropCount / 2) : ((cropCount + 1) / 2) )
+								if(mode === 'A4'){
+									PDF = new JsPDF({
+										orientation: 'p',
+										unit: 'mm',
+										format: 'a4',
+										putOnlyUsedFonts: true
+									})
+									PDF.setFont('Times New Roman')
+									PDF.setFontSize(12);
+									let curPage = 1
+									// 如果是一页的情况
+									if (leftHeight <= pageHeight) {
+										PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth,
+											imgHeight)
+										pdfDrawInfo(1)
+									} else {
+										// 如果超出则多页
+										while (leftHeight > 0) {
+											PDF.addImage(pageData, 'JPEG', 0, position,
+												imgWidth, imgHeight)
+											leftHeight -= pageHeight
+											position -= a4Height
+											pdfDrawInfo(curPage)
+											if (leftHeight > 0) {
+												PDF.addPage()
+											}
+											curPage++
+										}
+									}
+								}else{
+									/* 渲染A3纸张 */
+									PDF = new JsPDF({
+										orientation: 'l',
+										unit: 'mm',
+										format: 'a3',
+										putOnlyUsedFonts: true
+									})
+									PDF.setFont('Times New Roman')
+									PDF.setFontSize(10);
+									let pageImgArr = segmentationImage(img, a4WidthPx, a4HeightPx);
+									console.error('截取原图',pageData)
+									let curPage = 1
+									// 如果是一页的情况
+									if (leftHeight <= pageHeight) {
+										PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth,imgHeight)
+										pdfDrawInfo(2)
+									} else {
+										// 如果超出则多页
+										while (leftHeight > 0) {
+											if(curPage % 2 === 0){
+												PDF.addImage(pageImgArr[curPage - 1], 'JPEG', a4Width, 0, a4Width, a4Height)
+												pdfDrawInfo(curPage)
+												leftHeight -= pageHeight
+												if (leftHeight > 0) {
+													PDF.addPage()
+												}
+											}else{
+												PDF.addImage(pageImgArr[curPage - 1], 'JPEG', 0, 0,a4Width, a4Height)
+												leftHeight -= pageHeight
+												if (leftHeight <= 0) {
+													pdfDrawInfo(totalPage * 2)
+												}
+											}
+											curPage++
 										}
 									}
 								}
@@ -63,5 +168,7 @@ export default {
 				}, 1000)
 			})
 		}
-	}
+	},
+	
+	
 }

+ 33 - 0
TEAMModelOS/ClientApp/src/utils/public.js

@@ -215,6 +215,18 @@ export default {
 			.randomId() +
 			'-' + this.randomId() + this.randomId() + this.randomId())
 	},
+	/* 获取mm与px的转换 */
+	getOneMmsPx (){
+		// 创建一个1mm宽的元素插入到页面,然后坐等出结果
+		let div = document.createElement("div");
+		div.id = "mm";
+		div.style.width = "1mm";
+		document.querySelector("body").appendChild(div);
+		// 原生方法获取浏览器对元素的计算值
+		let mm1 = document.getElementById("mm").getBoundingClientRect();
+		console.log(mm1);
+		return mm1.width;
+	},
 	
 	// 根据总分和数量求平均结果
 	doAverage(total,count,step){
@@ -224,6 +236,27 @@ export default {
 		return tempArr
 	},
 	
+	getBoxPos(x,y,w,h){
+		return [
+			{
+				x:x,
+				y:y
+			},
+			{
+				x:x+w,
+				y:y
+			},
+			{
+				x:x+w,
+				y:y+h
+			},
+			{
+				x:x,
+				y:y+h
+			}
+		]
+	},
+	
 	matchHost(url){
 		var pattern = /[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/
 		return 'https://' + url.match(pattern)[0]

+ 1 - 1
TEAMModelOS/ClientApp/src/utils/sheetConfig.js

@@ -13,7 +13,7 @@ const SVG_BORDER_PROP = {
     x:15,
     y:20,
     width:PAPER_W - 15 * 2,
-    height:PAPER_H - 100
+    height:PAPER_H - 90
 }
 const SVG_BORDER_MB = PAPER_H - SVG_BORDER_PROP.y - SVG_BORDER_PROP.height
 const CONTENT_MT = 10; // 内容与定位框间隔

+ 3 - 3
TEAMModelOS/ClientApp/src/view/Home.vue

@@ -46,7 +46,7 @@ export default {
         }
     },
     created() {
-        console.log('刷新页面')
+        console.log('config',this.$store.state.config)
         // 检查超时操作页面,清空缓存数据
         let webEndTime = localStorage.getItem('webEndTime')
         let time_now = new Date().getTime()
@@ -57,7 +57,7 @@ export default {
         this.$store.dispatch('user/checkSchoolCode');// 設定登入成功的學校簡碼
         this.$store.dispatch('user/checkUserProfile');// 檢查使用者個人詳細資訊
         this.$store.dispatch('user/checkStudentProfile');// 檢查學生的詳細資訊
-        this.$store.dispatch('config/checkSrvAdr');// 檢查現在站的位置
+        
         // this.$store.dispatch('user/checkSchoolProfile').then(res => {
         //     if (res) {
         //         this.$User.freshLogin()
@@ -103,7 +103,7 @@ export default {
             window.location.href = window.location.origin + '/login'
         },
         reload() {
-            console.error('reload==============================')
+            // console.error('reload==============================')
             this.isRouterAlive = false
             this.$nextTick(() => {
                 this.isRouterAlive = true

+ 4 - 4
TEAMModelOS/ClientApp/src/view/ability/TestPaper.vue

@@ -184,7 +184,7 @@
 					let sasData = {
 						sas: '?' + this.$store.state.user.userProfile.osblob_sas,
 						name: 'teammodelos',
-						url: s.split(s.substring(s.lastIndexOf('/')))[0]
+						url: this.$evTools.getBlobHost(s)
 					}
 					//初始化Blob
 					let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas, 'school')
@@ -209,7 +209,7 @@
 					let sasData = {
 						sas: '?' + this.$store.state.user.userProfile.osblob_sas,
 						name: 'teammodelos',
-						url: s.split(s.substring(s.lastIndexOf('/')))[0]
+						url: this.$evTools.getBlobHost(s)
 					}
 					//初始化Blob
 					let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas, 'school')
@@ -262,7 +262,7 @@
 					let sasData = {
 						sas: '?' + this.$store.state.user.userProfile.osblob_sas,
 						name: 'teammodelos',
-						url: s.split(s.substring(s.lastIndexOf('/')))[0]
+						url: this.$evTools.getBlobHost(s)
 					}
 					//初始化Blob
 					let containerClient = new blobTool(
@@ -312,7 +312,7 @@
 						let sasData = {
 							sas: '?' + this.$store.state.user.userProfile.osblob_sas,
 							name: 'teammodelos',
-							url: s.split(s.substring(s.lastIndexOf('/')))[0]
+							url: this.$evTools.getBlobHost(s)
 						}
 						//初始化Blob
 						let containerClient = new blobTool(

+ 13 - 0
TEAMModelOS/ClientApp/src/view/areaMgmt/AreaBase.vue

@@ -41,6 +41,18 @@ export default {
         }
     },
     created() {
+		// 检查超时操作页面,清空缓存数据
+		let webEndTime = localStorage.getItem('webEndTime')
+		let time_now = new Date().getTime()
+		if (webEndTime && time_now > webEndTime) {
+		    console.log('长时间未操作,清空storage,重新登录')
+		    this.loginOut()
+		}
+		this.$store.dispatch('user/checkSchoolCode');// 設定登入成功的學校簡碼
+		this.$store.dispatch('user/checkUserProfile');// 檢查使用者個人詳細資訊
+		this.$store.dispatch('user/checkStudentProfile');// 檢查學生的詳細資訊
+		
+		
         let user = JSON.parse(decodeURIComponent(localStorage.userInfo, "utf-8"))
         let user_profile = JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8"))
         console.log(user_profile)
@@ -156,6 +168,7 @@ export default {
             return this.$store.state.userInfo.hasSchool;
         },
 		hasArea(){
+			console.error(this.$store.state.user.userProfile)
 			return this.$store.state.user.userProfile.areas.length > 0
 		}
     },

+ 16 - 18
TEAMModelOS/ClientApp/src/view/classrecord/ClassRecord.less

@@ -17,7 +17,7 @@
 
     .course-name {
         background: #1CC0F3;
-        padding: 4px 13px;
+        padding: 2px 15px;
         margin-right: 10px;
         color: white;
         border-radius: 18px;
@@ -26,15 +26,14 @@
     }
 
     .record-name {
-        color: white;
         font-size: 18px;
         font-weight: bold;
         vertical-align: top;
     }
 
-    .label-text {
-        color: white;
-    }
+    // .label-text {
+    //     color: white;
+    // }
 
     .label-value {
         color: #1CC0F3;
@@ -115,13 +114,13 @@
 }
 
 .content-title {
-    border-left: 10px solid #1CC0F3;
-    color: white;
+    border-left: 8px solid #1CC0F3;
+    // color: white;
     padding-left: 14px;
     line-height: 20px;
     font-size: 20px;
     margin-top: 25px;
-    margin-bottom: 20px;
+    margin-bottom: 6px;
 }
 
 .page-content {
@@ -159,9 +158,9 @@
 
 .interaction-record-wrap {
     width: 100%;
-    box-shadow: 5px 5px 500px #404040 inset;
+    box-shadow: 5px 5px 500px #f0f0f0 inset;
     border-radius: 4px;
-    border: 1px solid #404040;
+    border: 1px solid #f0f0f0;
     margin-bottom: 10px;
     position: relative;
     /*padding: 40px 80px 20px 50px;*/
@@ -216,11 +215,11 @@
     right: 10px;
     top: 0px;
     text-align: center;
-    background: rgba(255, 255, 255, 0.1);
+    background: white;
     z-index:999;
     .type-icon {
         font-size: 30px;
-        color: white;
+        // color: white;
         display: block;
         cursor: pointer;
         margin-bottom: 15px;
@@ -303,7 +302,7 @@
         margin-top: 5px;
 
         .question-info {
-            color: white;
+            // color: white;
         }
 
         &::before {
@@ -337,7 +336,7 @@
     display: none;
 
     .tools-icon {
-        color: white;
+        // color: white;
         font-size: 16px;
         cursor: pointer;
         margin-right: 15px;
@@ -393,13 +392,12 @@
     position: absolute;
     left: 0px;
     bottom: -24px;
-    color: white;
 }
 .answer-time {
     position: absolute;
     right: 0px;
     bottom: -24px;
-    color: white;
+    // color: white;
 }
 
 .message-info {
@@ -407,11 +405,11 @@
 }
 
 .student-name {
-    color: white
+    color: #1cc0f3;
 }
 
 .text-label {
-    color: white;
+    // color: white;
     margin-bottom: 10px;
     /*display:inline-block;
     vertical-align:top;*/

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 548 - 588
TEAMModelOS/ClientApp/src/view/classrecord/ClassRecord.vue


+ 3 - 3
TEAMModelOS/ClientApp/src/view/classrecord/CorrectRate.vue

@@ -10,9 +10,9 @@
                 option: {
                     title: {
                         text: '正确率统计',
-                        textStyle: {
-                            color: 'white'
-                        },
+                        // textStyle: {
+                        //     color: 'white'
+                        // },
                         right: '70',
                         top:'10'
                     },

+ 19 - 19
TEAMModelOS/ClientApp/src/view/classrecord/OptionCount.vue

@@ -10,9 +10,9 @@
                 option: {
                     title: {
                         text: '选项分布',
-                        textStyle: {
-                            color: 'white'
-                        },
+                        // textStyle: {
+                        //     color: 'white'
+                        // },
                         right: '85',
                         top:'10'
                     },
@@ -34,26 +34,26 @@
                     xAxis: {
                         type: 'value',
                         boundaryGap: [0, 0.01],
-                        axisLabel: {
-                            color:'white'
-                        },
-                        axisLine: {
-                            lineStyle: {
-                                color:'white'
-                            }
-                        }
+                        // axisLabel: {
+                        //     color:'white'
+                        // },
+                        // axisLine: {
+                        //     lineStyle: {
+                        //         color:'white'
+                        //     }
+                        // }
                     },
                     yAxis: {
                         type: 'category',
                         data: ['A', 'B', 'C', 'D'],
-                        axisLabel: {
-                            color:'white'
-                        },
-                        axisLine: {
-                            lineStyle: {
-                                color:'white'
-                            }
-                        }
+                        // axisLabel: {
+                        //     color:'white'
+                        // },
+                        // axisLine: {
+                        //     lineStyle: {
+                        //         color:'white'
+                        //     }
+                        // }
                     },
                     series: [
                         {

+ 82 - 68
TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue

@@ -2,9 +2,8 @@
 	<div class="pl-container" ref="plContainer">
 		<!-- 条件筛选部分 -->
 		<BaseFilter ref="baseFilter" @onChange="onFilterChange" :filterCounts="filterCounts"
-		 :isFilterPaper="isFilterPaper"
-		   v-show="!isPreview"></BaseFilter>
-		   
+			:isFilterPaper="isFilterPaper" v-show="!isPreview"></BaseFilter>
+
 		<div class="bank-action-bar light-iview-select light-iview-input" v-show="!isPreview">
 			<!-- 试卷列表的搜索功能 -->
 			<div class="action-tools">
@@ -15,13 +14,16 @@
 					</Select>
 				</div>
 				<div class="action-tool">
-					<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"/>
+					<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>
 			<div class="action-tools">
-				<span>{{ $t('evaluation.exerciseList.totalTip1') }}<span style="font-size: 18px;color: #ff0206;margin: 0 10px;font-weight: bold;">{{ totalNum }}</span>{{ $t('unit.text3') }}</span>
+				<span>{{ $t('evaluation.exerciseList.totalTip1') }}<span
+						style="font-size: 18px;color: #ff0206;margin: 0 10px;font-weight: bold;">{{ totalNum }}</span>{{ $t('unit.text3') }}</span>
 			</div>
-		</div>  
+		</div>
 
 		<!-- 空数据展示 -->
 		<div v-if="paperList.length === 0" class="no-data-text">
@@ -37,6 +39,7 @@
 					<div class="paper-item-name">
 						<span class="paper-item-tag" v-if="isSchool">{{ paper.subjectName }}</span>
 						<span style="margin-left: 8px;">{{ paper.name }}</span>
+						<span style="margin-left: 8px;" v-for="(tag,tagIndex) in paper.tags"><Tag color="geekblue" style="vertical-align: sub;">{{ tag }}</Tag></span>
 					</div>
 					<div class="paper-item-info">
 						<span class="info-item" v-if="isSchool">{{$t('evaluation.paperList.usePeriod')}}:<span
@@ -51,7 +54,10 @@
 								class="info-bold">{{ paper.useCount || 0 }}</span></span> -->
 						<span class="info-item">{{$t('evaluation.updateTime')}}:<span
 								class="info-bold">{{ $tools.formatTime(paper.createTime)  || 0 }} </span></span>
-						<!-- <span class="info-item">难度系数:<span class="info-bold">{{ paper.item ? handleDiffCalc(paper.item) : 0 }}</span></span> -->
+						<!-- <span class="info-item">
+							<span>标签:</span>
+							<span class="info-bold" v-for="(tag,tagIndex) in paper.tags"><Tag color="blue">{{ tag }}</Tag></span>
+						</span> -->
 					</div>
 					<div class="paper-item-tools" v-if="!chooseModel">
 						<!-- <span class="paper-item-tools-edit" @click.stop="goToDownload(paper)">
@@ -74,15 +80,16 @@
 						</span>
 					</div>
 					<div v-if="chooseModel" class="paper-item-select">
-						<div @click.stop="onCheckPaper(paper)" v-if="!checkedPaperList.length || (checkedPaperList.length && !checkedPaperList.map(i => i.id).includes(paper.id))">
+						<div @click.stop="onCheckPaper(paper)"
+							v-if="!checkedPaperList.length || (checkedPaperList.length && !checkedPaperList.map(i => i.id).includes(paper.id))">
 							<Icon type="md-add" />
 							<span>{{$t('evaluation.paperList.choosePaper')}}</span>
 						</div>
 						<div @click.stop="onCancelCheck(paper)" v-else>
-							<Icon type="md-checkmark-circle" color="#32b67b"/>
+							<Icon type="md-checkmark-circle" color="#32b67b" />
 							<span>{{$t('evaluation.paperList.choosed')}}</span>
 						</div>
-						
+
 					</div>
 				</div>
 
@@ -90,7 +97,7 @@
 				<Page :total="totalNum" show-sizer show-total :page-size="pageSize" :current="pageNum"
 					@on-page-size-change="pageSizeChange" @on-change="pageChange" :page-size-opts="[10,20,30,40]" />
 			</div>
-			
+
 			<!-- 预览试卷部分 -->
 			<div class="pl-review-wrap animated fadeIn" v-if="isPreview">
 				<div class="pl-review-wrap-left">
@@ -101,25 +108,26 @@
 					<h2>{{$t('evaluation.paperList.paperAnalysis')}}</h2>
 					<p style="margin-bottom: 20px;margin-top: 10px;">
 						({{$t('evaluation.paperList.totalScore')}}:{{ evaluationInfo.score }}
-						{{$t('evaluation.paperList.score')}})</p>
+						{{$t('evaluation.paperList.score')}})
+					</p>
 					<BaseTypePie :echartsData="evaluationInfo"></BaseTypePie>
 					<BaseObjectivePie :echartsData="evaluationInfo"></BaseObjectivePie>
 					<BaseDiffPie :echartsData="evaluationInfo"></BaseDiffPie>
 					<BasePointPie :echartsData="evaluationInfo"></BasePointPie>
 				</div>
 			</div>
-			
+
 			<!-- 预览答题卡部分 -->
 			<!-- <div class="pl-answersheet-wrap animated fadeIn" v-if="isShowSheet">
 				<AnswerSheet></AnswerSheet>
 			</div> -->
 		</div>
-		
-		<Modal v-model="isShowDownLoad" width="800px"  title="下载试卷" class-name="preview-modal">
+
+		<Modal v-model="isShowDownLoad" width="800px" title="下载试卷" class-name="preview-modal">
 			<DownloadPaper :paper="fullPaperJson"></DownloadPaper>
 		</Modal>
-		
-<!-- 		<Modal v-model="isShowSheet" width="800px"  title="答题卡" class-name="preview-modal" >
+
+		<!-- 		<Modal v-model="isShowSheet" width="800px"  title="答题卡" class-name="preview-modal" >
 			<div v-if="isShowSheet">
 				<AnswerSheet></AnswerSheet>
 			</div>
@@ -133,10 +141,10 @@
 	import BaseImport from '../components/BaseImport'
 	import TestPaper from '../index/TestPaper.vue'
 	export default {
-		props:{
-			chooseModel:{
-				type:Boolean,
-				default:false
+		props: {
+			chooseModel: {
+				type: Boolean,
+				default: false
 			}
 		},
 		components: {
@@ -147,11 +155,11 @@
 		},
 		data() {
 			return {
-				selectTags:[],
-				tags:[],
-				searchVal:'',
-				checkedPaperList:[],
-				isShowSheet:false,
+				selectTags: [],
+				tags: [],
+				searchVal: '',
+				checkedPaperList: [],
+				isShowSheet: false,
 				containerClient: null,
 				schoolCode: '',
 				totalNum: 0,
@@ -167,7 +175,7 @@
 				filterParams: {},
 				findCountParams: {},
 				originList: [],
-				originRes:[],
+				originRes: [],
 				schoolInfo: {},
 				filterSort: 'createTime',
 				evaluationInfo: null,
@@ -178,49 +186,50 @@
 					item: []
 				},
 				fullPaperJson: {
-					id:'0'
+					id: '0'
 				},
 				isShowDownLoad: false,
-				flag:false,
-				filterCounts:{
-					gradeCountArr:[],
-					subjectCountArr:[],
-					periodCountArr:[]
+				flag: false,
+				filterCounts: {
+					gradeCountArr: [],
+					subjectCountArr: [],
+					periodCountArr: []
 				},
-				isShowSchoolBank:false
+				isShowSchoolBank: false
 			}
 		},
 		created() {
 			// this.getPaperList()
 			// this.doFilter()
 			this.isShowSchoolBank = this.$route.name === "schoolBank";
-			
+
 		},
 		activated() {
 			this.isShowSchoolBank = this.$route.name === "schoolBank";
 		},
 		methods: {
-			
-			onCheckPaper(item){
+
+			onCheckPaper(item) {
 				console.log(item)
 				this.checkedPaperList.push(item)
 			},
-			
-			onCancelCheck(item){
-				this.checkedPaperList.splice(this.checkedPaperList.indexOf(item),1)
+
+			onCancelCheck(item) {
+				this.checkedPaperList.splice(this.checkedPaperList.indexOf(item), 1)
 			},
 
 			async onPreviewPaper(paper) {
-				if(this.chooseModel){
-					this.$emit('previewPaper',paper)
+				if (this.chooseModel) {
+					this.$emit('previewPaper', paper)
 					return
 				}
 				this.dataLoading = true
 				let curPaper = paper
-				sessionStorage.setItem('isSave',0)
+				sessionStorage.setItem('isSave', 0)
 				try {
 					// 获取完整试卷数据再跳转编辑页面
-					let fullPaperJson = this.fullPaperJson.id === curPaper.id ? this.fullPaperJson : await this.$evTools.getFullPaper(curPaper)
+					let fullPaperJson = this.fullPaperJson.id === curPaper.id ? this.fullPaperJson : await this
+						.$evTools.getFullPaper(curPaper)
 					this.fullPaperJson = fullPaperJson
 					fullPaperJson.code = curPaper.code
 					fullPaperJson.sheet = curPaper.sheet
@@ -281,7 +290,7 @@
 			doFilter(filterKey) {
 				this.dataLoading = true
 				this.isPreview = false
-				this.getPaperList(this.filterParams,filterKey)
+				this.getPaperList(this.filterParams, filterKey)
 			},
 
 			onFilterChange(val) {
@@ -296,19 +305,21 @@
 					"gradeIds[*]": isSchool ? filterParams.gradeIds : [],
 					'subjectId': isSchool ? filterParams.subjectId : []
 				}
-				if(filterParams.filterSort){
+				if (filterParams.filterSort) {
 					this.filterParams['@DESC'] = 'createTime'
-				}else{
+				} else {
 					this.filterParams['@ASC'] = 'createTime'
 				}
 				this.doFilter(filterKey)
 			},
 			/** 获取试卷列表 */
-			getPaperList(params,filterKey) {
+			getPaperList(params, filterKey) {
 				let that = this
 				this.$api.learnActivity.FindExamPaper(params).then(async res => {
 					let list = res.papers
-					if((!this.flag && this.periodList.length && this.filterParams.code === this.$store.state.userInfo.schoolCode) || (!this.flag && !this.isShowSchoolBank && this.filterParams.code === this.$store.state.userInfo.schoolCode)){
+					if ((!this.flag && this.periodList.length && this.filterParams.code === this.$store.state
+							.userInfo.schoolCode) || (!this.flag && !this.isShowSchoolBank && this.filterParams
+							.code === this.$store.state.userInfo.schoolCode)) {
 						this.filterCounts.periodCountArr = this.getPeriodCount(res.papers)
 						list = res.papers.filter(i => i.periodId === this.periodList[0].id)
 						this.flag = true
@@ -318,9 +329,9 @@
 					this.originList = list
 					this.originRes = JSON.parse(JSON.stringify(list))
 					this.totalNum = list.length
-					if(list.length){
+					if (list.length) {
 						this.tags = [...new Set(list.map(i => i.tags).flat(1))]
-						sessionStorage.setItem('paperTags',JSON.stringify(this.tags))
+						sessionStorage.setItem('paperTags', JSON.stringify(this.tags))
 					}
 					this.pageChange(1)
 					setTimeout(() => {
@@ -349,24 +360,25 @@
 				this.pageChange(1)
 			},
 			/* 标签选择发生变化 */
-			onTagChange(val){
-				this.originList = val.length ? this.originRes.filter(i => val.find(j => i.tags.includes(j))) : this.originRes
+			onTagChange(val) {
+				this.originList = val.length ? this.originRes.filter(i => val.find(j => i.tags.includes(j))) : this
+					.originRes
 				this.totalNum = this.originList.length
 				this.pageChange(1)
 			},
 			/* 获取所有学段下的试题总数 */
-			getPeriodCount(papers){
+			getPeriodCount(papers) {
 				let periodIdArr = this.periodList.map(i => i.id)
 				let periodCountArr = periodIdArr.map(i => {
 					return papers.filter(j => j.periodId === i).length
 				})
 				return periodCountArr
 			},
-			
+
 			/* 获取试题的年级、科目的数量统计 */
-			getItemsCount(papers,filterKey){
-				if(filterKey === 'period' || !filterKey){
-					let gradeIdArr = this.$refs.baseFilter.gradeList.map((i,index) => index)
+			getItemsCount(papers, filterKey) {
+				if (filterKey === 'period' || !filterKey) {
+					let gradeIdArr = this.$refs.baseFilter.gradeList.map((i, index) => index)
 					this.filterCounts.gradeCountArr = gradeIdArr.map(i => {
 						return papers.filter(j => j.gradeIds && j.gradeIds.includes(i + '')).length
 					})
@@ -375,7 +387,7 @@
 						return papers.filter(j => j.subjectId === i).length
 					})
 				}
-				
+
 				console.log(this.filterCounts);
 			},
 
@@ -385,10 +397,11 @@
 			 */
 			async goToPaper(paper) {
 				this.dataLoading = true
-				sessionStorage.setItem('isSave',0)
+				sessionStorage.setItem('isSave', 0)
 				try {
 					// 获取完整试卷数据再跳转编辑页面
-					let fullPaperJson = this.fullPaperJson.id === paper.id ? this.fullPaperJson : await this.$evTools.getFullPaper(paper)
+					let fullPaperJson = this.fullPaperJson.id === paper.id ? this.fullPaperJson : await this.$evTools
+						.getFullPaper(paper)
 					this.fullPaperJson = fullPaperJson
 					fullPaperJson.code = paper.code
 					fullPaperJson.sheet = paper.sheet
@@ -409,7 +422,8 @@
 
 			/* 下载试卷 */
 			async goToDownload(paper) {
-				let fullPaperJson = this.fullPaperJson.id === paper.id ? this.fullPaperJson : await this.$evTools.getFullPaper(paper)
+				let fullPaperJson = this.fullPaperJson.id === paper.id ? this.fullPaperJson : await this.$evTools
+					.getFullPaper(paper)
 				this.fullPaperJson = fullPaperJson
 				this.isShowDownLoad = true
 				console.log('要下载的试卷', fullPaperJson)
@@ -513,7 +527,8 @@
 			 * @param code
 			 */
 			getPeriodName(code) {
-				return code && this.$store.state.user.schoolProfile.school_base ? this.$store.state.user.schoolProfile.school_base
+				return code && this.$store.state.user.schoolProfile.school_base ? this.$store.state.user.schoolProfile
+					.school_base
 					.period.filter(i => i.id === code)[0].name : this.$t('evaluation.noData')
 			},
 
@@ -559,20 +574,19 @@
 </style>
 
 <style>
-	
-	.preview-modal .ivu-modal-body{
+	.preview-modal .ivu-modal-body {
 		/* height: 650px; */
 		overflow: scroll;
 	}
-	
+
 	.pl-content-wrap .ivu-page {
 		display: flex;
 		flex-direction: row;
 		justify-content: center;
 		margin: 20px 0;
 	}
-	
-	.pl-review-wrap-left .paper-base-info{
+
+	.pl-review-wrap-left .paper-base-info {
 		top: 50px !important;
 	}
 

+ 1 - 1
TEAMModelOS/ClientApp/src/view/evaluation/bank/index.less

@@ -24,7 +24,7 @@
 
     .ev-list-operation {
         position: fixed;
-		top: 65px;
+		top: 45px;
         right: 10px;
         height: 60px;
         display: flex;

+ 2 - 2
TEAMModelOS/ClientApp/src/view/evaluation/bank/index.vue

@@ -109,13 +109,13 @@
 			},
 
 			/** 前往组卷页面 */
-			goCreatePaper(type,isFromItemBank) {
+			goCreatePaper(type) {
 				this.$router.push({
 					name: this.$route.name === 'personalBank' ? 'newPrivatePaper' : 'newSchoolPaper',
 					params:{
 						scope : this.$route.name === 'personalBank' ? 'private' : 'school',
 						type: type,
-						isFromItemBank:isFromItemBank
+						isFromItemBank:this.currentTab === 'exercise'
 					}
 				})
 			},

+ 1 - 1
TEAMModelOS/ClientApp/src/view/evaluation/index/CommonExercise.less

@@ -115,7 +115,7 @@
     height: auto;
     padding: 10px 20px 10px 20px;
     margin-bottom: 10px;
-    font-size: 14px;
+    font-size: 16px;
     background: #fff;
     border: 2px solid transparent;
     cursor: pointer;

+ 3 - 14
TEAMModelOS/ClientApp/src/view/evaluation/index/CreateExercises.less

@@ -16,7 +16,10 @@
 
     .ev-container .w-e-text-container {
 		z-index:0 !important;
+		height:auto !important;
         min-height:150px !important;
+		max-height:350px !important;
+		overflow:auto;
     }
 
     .ev-container .ev-title {
@@ -285,14 +288,6 @@ exersices-attr-diff {
 		}
 	}
 }
-
-.ivu-spin-fix{
-	background-color: transparent !important;
-}
-
-
-
-
 .save-wrap {
     width:100%;
     justify-content:center;
@@ -304,12 +299,6 @@ exersices-attr-diff {
            margin-top:25px;
     }
 
-
-.w-e-text p, .w-e-text h1, .w-e-text h2, .w-e-text h3, .w-e-text h4, .w-e-text h5, .w-e-text table, .w-e-text pre {
-    /* display:inline-block; */
-}
-
-
 .ev-container .btn-upload {
     position:absolute;
     left:92%;

+ 2 - 4
TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue

@@ -35,7 +35,7 @@
 									<Input v-special-char v-model="evaluationInfo.name"></Input>
 								</FormItem>
 								<FormItem :label="$t('evaluation.paperTag')"  v-show="isGeneratePaper">
-									<Select v-model="evaluationInfo.tags" filterable multiple allow-create
+									<Select v-model="evaluationInfo.tags" filterable multiple allow-create :placeholder="$t('evaluation.paperTagPlace')"
 										@on-create="createTag">
 										<Option v-for="item in tags" :value="item" :key="item">{{ item }}</Option>
 									</Select>
@@ -1462,8 +1462,7 @@
 					.id : null
 			},
 			propGrades() {
-				console.error(this.evaluationInfo.paperGrade)
-				return this.$route.name === 'newSchoolPaper' && this.gradeList.length ? this.evaluationInfo.paperGrade : null
+				return this.$route.name === 'newSchoolPaper' && this.gradeList.length ? this.evaluationInfo.paperGrade : []
 			}
 		},
 
@@ -1489,7 +1488,6 @@
 								this.schoolInfo = res
 								this.evaluationInfo.paperPeriod = n.periodIndex
 								this.onPeriodChange(n.periodIndex)
-								console.error('进行了学段切换',n.periodIndex)
 							})
 						}else{
 							sessionStorage.setItem('isEditPaper',0)

+ 2 - 1
TEAMModelOS/ClientApp/src/view/evaluation/index/TestPaper.vue

@@ -194,7 +194,7 @@
 				this.downLoading = true
 				let examId = this.paperInfo.examId
 				let pdfName = `${this.paperInfo.name}-${this.paperInfo.sheetNo}.pdf`
-				let path = examId ? `exam/${examId}/paper/${this.paperInfo.name}/` : `paper/${this.paperInfo.name}/`
+				let path = examId ? `exam/${examId}/paper/${this.paperInfo.subjectId}/` : `paper/${this.paperInfo.name}/`
 				let curScope = examId ? this.paperInfo.examScope : this.paperInfo.scope
 				let cntr = curScope === 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
 				let sasData = curScope === 'school' ? await this.$tools.getSchoolSas() : await this.$tools.getPrivateSas()
@@ -219,6 +219,7 @@
 					localStorage.setItem('c_edit_paper', JSON.stringify(this.paperInfo))
 				}
 				console.log(this.paperInfo)
+				this.$store.commit('clearAllConfig')
 				this.$router.push({
 					name: 'answerSheet',
 					params: {

+ 2 - 2
TEAMModelOS/ClientApp/src/view/jyzx/application.vue

@@ -49,7 +49,7 @@
                         </div>
                     </TabPane>
                     <TabPane :label="$t('jyzx.application.discuss')" name="name2">
-                        <EmptyData textContent="暂无数据" v-if="!otherList.length"></EmptyData>
+                        <EmptyData :textContent="$t('jyzx.common.noData')" v-if="!otherList.length"></EmptyData>
                         <div v-else class="app-table">
                             <Table :columns="comCol" :data="otherList">
 								 <template slot-scope="{ row }" slot="myAppraise">
@@ -73,7 +73,7 @@
                 <span>{{ $store.state.userInfo.name }} 【 {{ curData.name }} 】</span>
             </div>
             <Table :columns="appraiseColumns" :data="appraiseArr" border>
-                <template slot-scope="{ row, index }" slot="result">
+                <template slot-scope="{ row }" slot="result">
                     <span v-show="row.result === '优秀'" style="color: #007700;">{{ $t('jyzx.application.fine') }}</span>
                     <span v-show="row.result === '合格'" style="color: orangered;">{{ $t('jyzx.application.qualified') }}</span>
                     <span v-show="row.result === '不合格'" style="color: red;">{{ $t('jyzx.application.unqualified') }}</span>

+ 3 - 3
TEAMModelOS/ClientApp/src/view/learnactivity/ByQuMark.vue

@@ -6,7 +6,7 @@
                 {{$t('learnActivity.score.quIndex')}}
             </span>
             <span class="qu-no-value qu-no-active" @click="toggleQuIndex">
-                {{quNoList.length ? quNoList[quIndex].label : '-'}}
+                {{quNoList && quNoList[quIndex] ? quNoList[quIndex].label : '-'}}
             </span>
             <span class="base-info-btn" type="success" @click="saveScore">
                 <Icon type="ios-albums-outline" />
@@ -35,7 +35,7 @@
         <div class="question-wrap" v-show="showQu">
             <p class="qu-info-title" style="display:block">{{$t('learnActivity.score.question')}}</p>
             <!-- 题号 -->
-            <span>{{ quNoList.length ? quNoList[quIndex].label : '' }} .</span>
+            <span>{{ quNoList && quNoList[quIndex] ? quNoList[quIndex].label : '' }} .</span>
             <!-- 题干 -->
             <span v-html="questionInfo.question"></span>
             <!-- 选项 -->
@@ -523,7 +523,7 @@ export default {
         },
         answerOrMark() {
             //如果当前老师已经批注过,再次批注就复用前面的批注数据
-            if (this.studentsData[this.stuIndex] && this.studentsData[this.stuIndex].mark) {
+            if (this.studentsData[this.stuIndex] && this.studentsData[this.stuIndex].mark  && this.studentsData[this.stuIndex].mark[this.quIndex]) {
                 let d = this._.cloneDeep(this.studentsData[this.stuIndex].mark[this.quIndex])
                 let markData = d.find(item => {
                     return item.tmdId == this.$store.state.userInfo.TEAMModelId

+ 2 - 2
TEAMModelOS/ClientApp/src/view/learnactivity/ByStuMark.vue

@@ -42,10 +42,10 @@
                 <div>
                     <template v-for="(typeItem,typeIndex) in groupList">
                         <template v-for="(item,index) in typeItem.list">
-                            <span :key="typeIndex+''+index" @click="goToQuestion(getScoreIndex(typeIndex,index))" :class="studentAnswer.scores[item.index] >= 0 ? 'qu-order-tag':'qu-order-tag-def'" v-if="typeItem.type !== 'compose'">
+                            <span :key="`${typeItem.type}${typeIndex}${index}`" @click="goToQuestion(getScoreIndex(typeIndex,index))" :class="studentAnswer.scores[item.index] >= 0 ? 'qu-order-tag':'qu-order-tag-def'" v-if="typeItem.type !== 'compose'">
                                 {{getQuIndex(typeIndex,index)}}
                             </span>
-                            <span :key="index" v-else>
+                            <span :key="`${typeItem.type}${typeIndex}${index}`" v-else>
                                 <span @click="goToQuestion(getScoreIndex(typeIndex,index,childIndex))" v-for="(childItem,childIndex) in item.children" :key="childIndex" :class="studentAnswer.scores[childItem.index] >= 0 ? 'qu-order-tag':'qu-order-tag-def'">
                                     {{getQuIndex(typeIndex,index) + '-' + (childIndex + 1)}}
                                 </span>

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

@@ -505,7 +505,7 @@
 			},
 			gradeCode:{
 				handler(n,o){
-					if(n && this.gradeList.length){
+					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')

+ 1 - 1
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.less

@@ -253,7 +253,7 @@
 }
 .record-action-wrap{
     float:right;
-    color:white;
+    // color:white;
     font-size:14px;
     padding-right:30px;
 }

+ 7 - 5
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue

@@ -126,11 +126,11 @@
                                 <List>
                                     <ListItem v-for="(item,index) in itemNum" :key="index">
                                         <ListItemMeta @click.native="toClassRecoerd">
-                                            <p slot="title" class="record-name">力的组成</p>
-                                            <span slot="avatar" style="margin-top:4px;display: inline-block;margin-left:10px;">
-                                                <Icon custom="iconfont icon-whiteboard" size="30" color="white" />
-                                            </span>
-                                            <div slot="description" style="color:white;">
+                                            <p slot="title" class="record-name" style="padding-left:10px">力的组成</p>
+                                            <!-- <span slot="avatar" style="margin-top:4px;display: inline-block;margin-left:10px;">
+                                                <Icon custom="iconfont icon-whiteboard" size="30"/>
+                                            </span> -->
+                                            <div slot="description" style="padding-left:10px">
                                                 <span class="hiteacher-version">
                                                     V3.0.32
                                                 </span>
@@ -1564,6 +1564,8 @@ export default {
         }
     },
     created() {
+        this.itemNum = this.$store.state.config.srvAdrType == 'product' ? 0 : 5
+
         this.getAllStuList()
         //直接读取登录成功拿到得学校基础信息
         this.$store.dispatch('user/getSchoolProfile').then(res => {

+ 32 - 40
TEAMModelOS/ClientApp/src/view/newsheet/BaseEditor.vue

@@ -125,12 +125,12 @@
 			},
 			
 			/* 设置填空题和简答题的配置数据 */
-			setSubjectiveConfig(y,height,isFix,startOrder,count){
+			setSubjectiveConfig(y,height,isFix,startOrder,count,type){
 				if(height === 0) return
 				let itemConfig = {
-					"type": 2,
+					"type": type,
 					"x": CONTENT_START_X - ANCHORPROP.gapX + 5,
-					"y": y - ANCHORPROP.gapY + 5,
+					"y": y - SVG_BORDER_PROP.y,
 					"width": INFO_W,
 					"height": height,
 					"pageNum": this.$store.state.answerSheet.pages,
@@ -138,7 +138,6 @@
 					"count":count,
 					"startOrder":startOrder
 				}
-				console.log(JSON.stringify(itemConfig))
 				this.$store.commit('setSubjectiveConfig', itemConfig)
 			},
 
@@ -195,18 +194,9 @@
 				switch (this.type) {
 					case "0":
 						this.doInsertComplete(items);
+						
 						break;
 					case "1":
-						// if(items[0].children.length){
-						// 	items[0].children.forEach((child,childIndex) => {
-						// 		child.id = items[0].id
-						// 		this.doInsertSubjective([child],childIndex + 1);
-						// 		console.error(childIndex,child)
-						// 	})
-							
-						// }else{
-						// 	this.doInsertSubjective(items);
-						// }
 						this.doInsertSubjective(items);
 						break;
 					default:
@@ -265,21 +255,23 @@
 						let editorDom = this.myEditor.$textElem.elems[0]
 						this.pArr = Array.from(editorDom.getElementsByTagName('p'))
 						let scrollDis = scrollDom.getPosition().scrollTop
-						let Y = editorDom.getBoundingClientRect().top + scrollDis - 90;
+						let Y = editorDom.getBoundingClientRect().top + scrollDis - 70;
 						let paperH = PAPER_H;
 						let lastBottomGap = 20;
 						let curEditorY = Y > paperH ? +((Y % paperH).toFixed(4)) : Y;
 						let curEditorH = editorDom.clientHeight;
-						
+						if (!curEditorH) return
+						// console.error(startOrder,'curEditorY',curEditorY)
+						// console.error(startOrder,'curEditorH',curEditorH)
 						let leftHeight = paperH - curEditorY - lastBottomGap - SVG_BORDER_MB;
-						let fixHeight = curEditorH - leftHeight + 20
+						let fixHeight = curEditorH - leftHeight
 						if ( curEditorY + curEditorH + lastBottomGap + SVG_BORDER_MB > PAPER_H) {
 							// 如果剩余高度不满足渲染 并且需要补充的区域 则需要进行跨页处理
 							if (leftHeight > 100) {
-								this.setSubjectiveConfig(curEditorY,leftHeight + 20,true,startOrder,items.length)
-								this.$store.commit("addPage");
+								this.setSubjectiveConfig(curEditorY,leftHeight,true,startOrder,items.length,4)
+								this.$store.commit("addPage",4);
 								let heightArr = []
-								this.myEditor.config.height = leftHeight + 20;
+								this.myEditor.config.height = leftHeight;
 								heightArr.push(leftHeight)
 								// 如果渲染的客观题高度在这个区间 才需要在下一页添加补充作答区域 其余全部按照正常 跨页处理不需要补充作答区域
 								let fixCount = Math.ceil(fixHeight / SVG_BORDER_PROP.height)
@@ -292,7 +284,7 @@
 										fixHeight = fixHeight - SVG_BORDER_PROP.height
 									if(i > 0) {
 										console.log('fix添加页码')
-										this.$store.commit("addPage");
+										this.$store.commit("addPage",4);
 									}
 								}
 								this.$nextTick(() => {
@@ -304,7 +296,7 @@
 										let editorHeight = curEditorContent.html === '' ? heightArr[editorIndex] : heightArr[editorIndex]
 										// let curEditorContent = this.getSplitHtml(this.pArr,curEditorHeight)
 										if(editorIndex !== 0){
-											this.initFixEditor(this.ids + 'fix' + (editorIndex - 1), editorHeight, curEditorContent.html,startOrder,items.length)
+											this.initFixEditor(this.ids + 'fix' + (editorIndex - 1), editorHeight, curEditorContent.html,startOrder,items.length,4)
 										}else{
 											this.myEditor.txt.clear();
 											this.myEditor.txt.html('<span></span>')
@@ -314,9 +306,9 @@
 								})
 							} else {
 								// 跨页处理不需要补充作答区域
-									this.$store.commit("addPage");
+									this.$store.commit("addPage",4);
 								// if(this.$parent.completeItems.map(i => i.id).indexOf(this.curItemId) === 0){
-									this.setSubjectiveConfig(100,curEditorH,false,startOrder,items.length)
+									this.setSubjectiveConfig(100,curEditorH,false,startOrder,items.length,4)
 									this.$EventBus.$emit('titleMovePage',{
 										type:'complete',
 										height:leftHeight
@@ -330,7 +322,7 @@
 							}
 						}else {
 							console.log(items);
-							this.setSubjectiveConfig(curEditorY,curEditorH,false,startOrder,items.length)
+							this.setSubjectiveConfig(curEditorY,curEditorH,false,startOrder,items.length,4)
 							document.getElementById(this.ids + 'btn').style.top =  "20px";
 						}
 					})
@@ -408,7 +400,7 @@
 						let isNewPage = this.$store.state.answerSheet.isNewPage;
 						let lastBottomGap = 20;
 						let rectTop = editorDom.getBoundingClientRect().top
-						let Y = scrollDis > 90 ? scrollDis - Math.abs(rectTop)  - 90 : rectTop + scrollDis - 90;
+						let Y = scrollDis > 70 ? scrollDis - Math.abs(rectTop)  - 70 : rectTop + scrollDis - 70;
 						let paperH = PAPER_H;
 						let curEditorY = Y > paperH ? +((Y % paperH).toFixed(4)) : Y;
 						let curEditorH = editorDom.clientHeight; // 默认200px
@@ -421,12 +413,12 @@
 							startPageIndex++
 							console.log('xxxx',itemOrder,leftHeight)
 							// 如果剩余高度满足渲染一部分区域 并且需要补充的区域 则需要进行跨页处理
-							if (leftHeight > 100) {
-								this.setSubjectiveConfig(curEditorY,leftHeight,true,configIndex,1)
+							if (leftHeight >= 100) {
+								this.setSubjectiveConfig(curEditorY,leftHeight,true,configIndex,1,3)
 								this.myEditor.config.height = leftHeight;
 								// 如果剩余要补充的区域高度大于50 才会进行添加补充框
 								if(fixHeight < 50) return
-								this.$store.commit("addPage");
+								this.$store.commit("addPage",3);
 								let heightArr = []
 								heightArr.push(leftHeight)
 								// 如果渲染的客观题高度在这个区间 才需要在下一页添加补充作答区域 其余全部按照正常 跨页处理不需要补充作答区域
@@ -438,18 +430,18 @@
 										fixHeight = fixHeight - SVG_BORDER_PROP.height + 30
 									if(i > 0) {
 										console.log('fix添加页码')
-										this.$store.commit("addPage");
+										this.$store.commit("addPage",3);
 									}
 								}
 								this.$nextTick(() => {
 									let splitHtmlArr = this.getSplitHtml(this.pArr,heightArr)
 									splitHtmlArr.forEach((curEditorContent,editorIndex) => {
-										// console.log('富文本的分割高度',heightArr)
-										// console.log('富文本的分割',splitHtmlArr)
+										console.log('富文本的分割高度',heightArr)
+										console.log('富文本的分割',splitHtmlArr)
 										let editorHeight = curEditorContent.html === '' ? heightArr[editorIndex] : heightArr[editorIndex]
 										// let curEditorContent = this.getSplitHtml(this.pArr,curEditorHeight)
 										if(editorIndex !== 0){
-											this.initFixEditor(this.ids + 'fix' + (editorIndex - 1), editorHeight, curEditorContent.html,configIndex,1)
+											this.initFixEditor(this.ids + 'fix' + (editorIndex - 1), editorHeight, curEditorContent.html,configIndex,1,3)
 										}else{
 											this.myEditor.txt.clear();
 											this.myEditor.txt.html('<span></span>')
@@ -459,22 +451,22 @@
 								})
 							} else {
 								// 跨页处理不需要补充作答区域
-								this.$store.commit("addPage");
+								this.$store.commit("addPage",3);
 								if(this.$parent.subjectiveItems.map(i => i.id).indexOf(this.curItemId) === 0){
-									this.setSubjectiveConfig(100,curEditorH,false,configIndex,1)
+									this.setSubjectiveConfig(100,curEditorH,false,configIndex,1,3)
 									this.$EventBus.$emit('titleMovePage',{
 										type:'subjective',
 										height:leftHeight
 									})
 								}else{
-									this.setSubjectiveConfig(curEditorY,curEditorH,false,configIndex,1)
+									this.setSubjectiveConfig(curEditorY,curEditorH,false,configIndex,1,3)
 									document.getElementById(this.ids).style.marginTop = (PAPER_H - curEditorY + lastBottomGap + SVG_BORDER_PROP.y) + "px";
 									document.getElementById(this.ids + 'btn').style.top = (PAPER_H - curEditorY + lastBottomGap + SVG_BORDER_PROP.y + 20) + "px";
 								}
 								
 							}
 						} else {
-							this.setSubjectiveConfig(curEditorY,curEditorH,false,configIndex,1)
+							this.setSubjectiveConfig(curEditorY,curEditorH,false,configIndex,1,3)
 							document.getElementById(this.ids + 'btn') && (document.getElementById(this.ids + 'btn').style.top =  "20px")
 						}
 						this.$root.$children[0].spinShow = false;
@@ -732,10 +724,10 @@
 			},
 			
 			/* 初始化补充富文本编辑器 */
-			initFixEditor(curId,height,content,itemOrder,count){
+			initFixEditor(curId,height,content,itemOrder,count,type){
 				console.log('补充编辑器',height)
 				let curItemWhichPage = this.$store.state.answerSheet.pages
-				this.setSubjectiveConfig(90,height,true,itemOrder,count)
+				this.setSubjectiveConfig(60,height,true,itemOrder,count,type)
 				const editor = new E("#" + curId);
 				editor.config.height = height;
 				editor.config.menus = [
@@ -799,7 +791,7 @@
 						content: html
 					})
 				};
-				document.getElementById(curId).style.marginTop = (SVG_BORDER_MB - 10) * 2  + "px";
+				document.getElementById(curId).style.marginTop = "148px";
 				editor.config.focus = false;
 				editor.config.showFullScreen = false;
 				editor.config.placeholder = "";

+ 13 - 24
TEAMModelOS/ClientApp/src/view/newsheet/BaseSvgBg.vue

@@ -45,17 +45,6 @@
 		components: {
 			BaseTitleEditor
 		},
-		created() {
-			// var reader = new FileReader();
-			//    // 读取文件作为URL可访问地址
-			//    var img = document.createElement("img");
-			// let s = 'file:///C:\Users\zxj\AppData\Local\Temp\ksohtml1436\wps8.jpg'
-			// let j = URL.createObjectURL(s)
-			//    img.src = j;
-			// document.getElementById('pdfDom').append(img)
-			// console.log(j)
-			// console.log(img)
-		},
 		methods: {
 			doRenderPageAnchor(snap) {
 				this.anchorBox.remove(); // 先清除之前的绘制内容
@@ -126,14 +115,14 @@
 			this.anchorBox = snap.paper.g();
 			this.sheetIdBox = snap.paper.g();
 			let anchorProp = ANCHORPROP;
-			snap
-				.rect(SVG_BORDER_PROP.x, SVG_BORDER_PROP.y, SVG_BORDER_PROP.width, SVG_BORDER_PROP.height)
-				.attr({
-					shapeRendering: "crispEdges",
-					fill: "none",
-					stroke: "#000",
-					strokeWidth: 1
-				});
+			// snap
+			// 	.rect(SVG_BORDER_PROP.x, SVG_BORDER_PROP.y, SVG_BORDER_PROP.width, SVG_BORDER_PROP.height)
+			// 	.attr({
+			// 		shapeRendering: "crispEdges",
+			// 		fill: "none",
+			// 		stroke: "#ff0000",
+			// 		strokeWidth: 1
+			// 	});
 
 			// 画四个锚点
 			// snap.rect(
@@ -213,9 +202,9 @@
 			// 	shapeRendering:"crispEdges"
 			// });
 			this.snap = snap;
-			this.doRenderPage(snap);
-			this.doRenderPageAnchor(snap);
-			this.doRenderId(snap);
+			// this.doRenderPage(snap);
+			// this.doRenderPageAnchor(snap);
+			// this.doRenderId(snap);
 
 		},
 		computed: {
@@ -232,10 +221,10 @@
 				immediate: true
 			},
 			total(n, o) {
-				this.doRenderPage(this.snap);
+				// this.doRenderPage(this.snap);
 			},
 			sheetId(n, o) {
-				this.doRenderId(this.snap);
+				// this.doRenderId(this.snap);
 			},
 		},
 	};

+ 15 - 34
TEAMModelOS/ClientApp/src/view/newsheet/SheetBaseInfo.vue

@@ -21,6 +21,7 @@
 	import {
 		PAPER_W,
 		PAPER_H,
+		SVG_BORDER_PROP,
 		CONTENT_MT,
 		CONTENT_ML,
 		ANCHORPROP,
@@ -93,10 +94,7 @@
 						});
 					this.infoLeftBox.add(leftInfo1, leftInfo2);
 				});
-
 				this.renderIdNumber(this.idLength, false);
-				this.$store.commit('setInfoMode', 'number')
-				this.$store.commit('setInfoPos', this.svgPosArr)
 				this.$EventBus.$emit('baseInfoModify')
 			},
 
@@ -104,7 +102,6 @@
 			renderIdNumber(idLength, isShowCode) {
 				let snap = this.snap;
 				this.svgPosArr = []
-				this.setInfoConfig()
 				this.idNumberBox.remove();
 				this.idNumberBox = snap.paper.g();
 
@@ -159,7 +156,7 @@
 						isShowCode ? this.$t('answerSheet.qrCodeTitle') : this.$t('answerSheet.idTitle')
 					)
 				);
-				if (!isShowCode) {
+				
 					this.idNumberBox.add(
 						// 填涂上边框
 						snap
@@ -241,39 +238,23 @@
 							})
 						}
 					});
-				} else {
-					// let img = require("@/static/qrCode.png");
-					// let c4 = snap.image(
-					// 	img,
-					// 	570,
-					// 	110,
-					// 	150,
-					// 	150
-					// );
-					// this.idNumberBox.add(c4);
-				}
-
-			},
-
-			renderQRCode() {
-				let snap = this.snap;
-				this.setInfoConfig()
-				this.idNumberBox.remove();
-				this.idNumberBox = snap.paper.g();
+				/* 二维码区域框的信息 */
+				let qrCodeBox_x = INFO_LEFT_X - SVG_BORDER_PROP.x
+				let qrCodeBox_y = CONTENT_MT + 50  - SVG_BORDER_PROP.y + 40
+				let qrCodeBoxPos = this.$tools.getBoxPos(qrCodeBox_x,qrCodeBox_y,CELL_WIDTH * idLength,INFO_H - 40)
+				this.setInfoConfig(isShowCode,qrCodeBoxPos)
 			},
 
-			setInfoConfig() {
+			/* 设置信息框的配置参数 */
+			setInfoConfig(isShowCode,qrCodeBoxPos) {
 				let infoConfig = {
-					"type": 0,
-					"x": CONTENT_START_X - ANCHORPROP.gapX + 5,
-					"y": CONTENT_START_Y - ANCHORPROP.gapY + 5,
-					"width": INFO_W,
-					"height": INFO_H,
+					"type": isShowCode ? 1 : 0,
 					"pageNum": 1,
-					"vblockCount": 10,
-					"hblockCount": this.idLength
+					"count": this.idLength,
+					"pos": this.$tools.getBoxPos(SVG_BORDER_PROP.x,CONTENT_START_Y - SVG_BORDER_PROP.y,INFO_W,INFO_H),
+					"points":isShowCode ? qrCodeBoxPos : this.svgPosArr
 				}
-				this.$store.commit('setInfoConfig', infoConfig)
+				this.$store.commit('addInfoContent', infoConfig)
 			}
 		},
 		mounted: function() {
@@ -294,7 +275,7 @@
 					strokeWidth: 1,
 					shapeRendering: "crispEdges",
 				});
-			this.setInfoConfig()
+			// this.setInfoConfig()
 
 
 			infoBox.mouseover(() => {

+ 12 - 1
TEAMModelOS/ClientApp/src/view/newsheet/SheetComplete.vue

@@ -70,7 +70,7 @@ export default {
     };
   },
   created() {
-    // this.snap = Snap("#sheetCompleteSvg");
+	
   },
   methods: {
   },
@@ -84,6 +84,17 @@ export default {
         this.isRender = true
       },)
     });
+	
+	/* 初始化填空题的配置参数 */
+	let initCompleteConfig = {
+		"type": 4,
+		"pageNum": 1,
+		"count": 0,
+		"pos": [],
+		"points": []
+	}
+	this.$store.commit('addCompleteContent',initCompleteConfig)
+	
   },
   computed:{
     totalScore(){

+ 16 - 11
TEAMModelOS/ClientApp/src/view/newsheet/SheetObjective.vue

@@ -81,6 +81,15 @@
 		},
 		created() {
 			this.snap = Snap("#sheetObjectiveSvg");
+			/* 初始化填空题的配置参数 */
+			let iniObjectiveConfig = {
+				"type": 2,
+				"pageNum": 1,
+				"count": 0,
+				"pos": [],
+				"points": []
+			}
+			this.$store.commit('addObjectiveContent',iniObjectiveConfig)
 		},
 		methods: {
 			doDelete() {
@@ -90,18 +99,16 @@
 			setObjectiveConfig(){
 				this.$store.commit('setColumnCount',this.number)
 				let titleHeight = document.getElementById('titleEditor0').getBoundingClientRect().height
+				let objectiveBox_x = CONTENT_START_X - ANCHORPROP.gapX + 5
+				let objectiveBox_y = 308 - (ANCHORPROP.gapY - 5) + titleHeight + 10
 				let objectiveConfig = {
-					"type": 1,
-					"x": CONTENT_START_X - ANCHORPROP.gapX + 5,
-					"y": 350 - (ANCHORPROP.gapY - 5) + titleHeight + 10,
-					"width": INFO_W,
-					"height": this.anchorRectY,
+					"type": 2,
 					"pageNum": 1,
-					"vblockCount": this.objectiveItems.length > this.number ? this.number * this.blockList.length : this.objectiveItems.length,
-					"hblockCount": OBJ_ANCHOR_H_COUNT,
-					"count": this.objectiveItems.length
+					"count": this.objectiveItems.length,
+					"pos":this.$tools.getBoxPos(objectiveBox_x,objectiveBox_y,INFO_W,this.anchorRectY),
+					"points":this.objectivePosArr,
 				}
-				this.$store.commit('setObjectiveConfig', objectiveConfig)
+				this.$store.commit('addObjectiveContent', objectiveConfig)
 			},
 			
 			// 修改每列展示题数重新渲染
@@ -303,8 +310,6 @@
 
 				// 渲染包围框
 				this.doRenderBorder(items, number, blockList.length);
-				this.$store.commit('setObjectivePos',this.objectivePosArr)
-				console.log(this.objectivePosArr)
 			},
 
 			// 获取每一列渲染的x坐标

+ 10 - 0
TEAMModelOS/ClientApp/src/view/newsheet/SheetSubjective.vue

@@ -98,6 +98,16 @@ export default {
         this.isRender = true
       },)
     });
+	
+	/* 初始化填空题的配置参数 */
+	let initSubjectiveConfig = {
+		"type": 3,
+		"pageNum": 1,
+		"count": 0,
+		"pos": [],
+		"points": []
+	}
+	this.$store.commit('addSubjectiveContent',initSubjectiveConfig)
   },
   computed:{
     totalScore(){

+ 109 - 22
TEAMModelOS/ClientApp/src/view/newsheet/index.vue

@@ -4,7 +4,7 @@
 			 <Icon type="ios-loading" size=18 class="demo-spin-icon-load"></Icon>
 			 <div>{{ $t('answerSheet.loading') }}</div>
 		</Spin> -->
-		
+		<!-- <Loading v-if="isLoading"></Loading> -->
 		<div class="sheet-left">
 			<div :class="['sheet-container',isLoading ? 'noEvent' : '']" id="pdfDom" v-if="isRender" >
 				<!-- <router-view  v-if="isRouterAlive"/> -->
@@ -23,7 +23,7 @@
 						<div v-else-if="group.type === 'complete'">
 							<BaseTitleEditor :ids="'titleEditor' + groupIndex" :content="titleContent(groupIndex,group)"
 								ref="completeTitleRef"></BaseTitleEditor>
-							<SheetComplete :items="items" v-if="groupItems.completeItems.length"></SheetComplete>
+							<SheetComplete :items="items" v-show="groupItems.completeItems.length"></SheetComplete>
 						</div>
 						<div v-else>
 							<BaseTitleEditor :ids="'titleEditor' + groupIndex" :content="titleContent(groupIndex,group)"
@@ -38,8 +38,10 @@
 		</div>
 		<div class="sheet-right">
 			<Button @click="goBack">{{ $t('answerSheet.back') }}</Button>
-			<Button @click="doDownload" class="btn-download"
+			<Button @click="pdfModal = true" class="btn-download"
 				:loading="isLoading">{{ !isLoading ? $t('answerSheet.print') : $t('answerSheet.loading') }}</Button>
+			<!-- <Button @click="doDownload('A3')" class="btn-download"
+				:loading="isLoading">A3</Button>	 -->
 			<div>
 				<p class="sheet-right-title">{{ $t('answerSheet.setting') }}</p>
 				<div>
@@ -125,6 +127,21 @@
 				<Button type="primary" @click="doAddType">{{ $t('answerSheet.confirm') }}</Button>
 			</div>
 		</Modal>
+	
+		<Modal v-model="pdfModal" class-name="add-type-modal pdf-modal" width="650" :title="$t('answerSheet.print')" @on-ok="onConfirmDownload">
+			<div class="pdf-wrap">
+				<div style="display: flex;flex-direction: column;align-items: center;">
+					<div :class="['a4', curMode ==='A4' ? 'mode-active' : '']" @click="curMode ='A4'">A4</div>
+					<p style="margin-top: 10px;">打印A4规格</p>
+					<p style="margin-top: 10px;font-size: 12px;">单栏 (210mm * 297mm)</p>
+				</div>
+				<div style="display: flex;flex-direction: column;align-items: center;">
+					<div :class="['a3', curMode ==='A3' ? 'mode-active' : '']" @click="curMode ='A3'">A3</div>
+					<p style="margin-top: 10px;">打印A3规格</p>
+					<p style="margin-top: 10px;font-size: 12px;">双栏 (420mm * 297mm)</p>
+				</div>
+			</div>
+		</Modal>
 	</div>
 </template>
 
@@ -142,7 +159,8 @@
 		PAPER_H,
 		ANCHORPROP,
 		INFO_H,
-		SVG_BORDER_MB
+		SVG_BORDER_MB,
+		SVG_BORDER_PROP
 	} from "@/utils/sheetConfig.js";
 	export default {
 		props: {
@@ -165,6 +183,7 @@
 		},
 		data(vm) {
 			return {
+				pdfModal:false,
 				curPaper: {
 					id: null
 				},
@@ -204,7 +223,8 @@
 					subjective: vm.$t('answerSheet.subjective')
 				},
 				hasModify:false,
-				examId:null
+				examId:null,
+				curMode:'A4'
 			};
 		},
 		created() {
@@ -234,6 +254,23 @@
 
 		},
 		methods: {
+			onConfirmDownload(){
+				this.$Spin.show({
+					render: (h) => {
+						return h('div', [
+							h('Icon', {
+								'class': 'demo-spin-icon-load',
+								props: {
+									type: 'ios-loading',
+									size: 18
+								}
+							}),
+							h('div', '下载中...')
+						])
+					}
+				});
+				this.doDownload(this.curMode)
+			},
 			onQrcode(val){
 				this.$EventBus.$emit('changeIdMode',val)
 			},
@@ -269,17 +306,14 @@
 					maxLines: 10
 				}
 			},
-
 			onStartChange(val) {
 				this.indexErr = val > this.addType.endIndex || (!val && !this.addType.endIndex)
 				this.renderAddItem()
 			},
-
 			onEndChange(val) {
 				this.indexErr = val < this.addType.startIndex || (!val && !this.addType.startIndex)
 				this.renderAddItem()
 			},
-
 			/* 点击添加题型 */
 			doAddType() {
 				if (this.isAddInfoComplete) {
@@ -298,7 +332,8 @@
 				}
 			},
 			/* 打印答题卡 */
-			doDownload() {
+			doDownload(mode) {
+				this.curMode = mode
 				if(this.curPaper.sheet && this.hasModify){
 					this.$Modal.confirm({
 						title: this.$t('answerSheet.tip22'),
@@ -312,14 +347,16 @@
 								if (this.isFromExam) {
 									this.$EventBus.$emit('createSheetId', res.config.no)
 								}
-								this.getPdf().then(async r => {
+								this.getPdf(mode,res.config.no).then(async r => {
 									await this.doUploadPDF(r)
 									this.isLoading = false
+									this.$Spin.hide();
 									this.hasModify = false
 								})
 							}).catch(err => {
 								console.log(err)
 								this.isLoading = false
+								this.$Spin.hide();
 							})
 						}
 					})
@@ -330,9 +367,10 @@
 					if(this.sheetId){
 						// 快速从BLOB进行下载
 						// this.downloadSheet()
-						this.getPdf().then(async r => {
+						this.getPdf(mode,this.sheetId).then(async r => {
 							await this.doUploadPDF(r)
 							this.isLoading = false
+							this.$Spin.hide();
 						})
 					}else{
 						// 没有答题卡ID 也无修改 就是新增答题卡
@@ -342,13 +380,15 @@
 							if (this.isFromExam) {
 								this.$EventBus.$emit('createSheetId', res.config.no)
 							}
-							this.getPdf().then(async r => {
+							this.getPdf(mode,this.sheetId).then(async r => {
 								await this.doUploadPDF(r)
 								this.isLoading = false
+								this.$Spin.hide();
 							})
 						}).catch(err => {
 							console.log(err)
 							this.isLoading = false
+							this.$Spin.hide();
 						})
 					}
 				}
@@ -407,16 +447,34 @@
 				return new Promise((r, j) => {
 					let paperInfo = this.$store.state.answerSheet.paperItem
 					let configParams = this.$store.state.answerSheet.config
-					configParams.columns = 1
-					configParams.contents.forEach(i => {
-						if(i.startOrder){
-							delete i.startOrder
+					delete configParams.contents
+					configParams.mode = this.curMode
+					configParams.newContents.forEach((outerBox,outerIndex) => {
+						// 如果是A3模式 则需要把 分割的偶数图(A3右边的那页) 里面的x坐标 进行相应的调整
+						if(this.curMode === 'A3'){
+							if(outerBox.pageNum % 2 === 0){
+								outerBox.points.forEach(i => {
+									i.pos.forEach(j => {
+										j.x += PAPER_W + SVG_BORDER_PROP.x
+									})
+								})
+								outerBox.pos.forEach(j => {
+									j.x += PAPER_W + SVG_BORDER_PROP.x
+								})
+							}
+							outerBox.pageNum = Math.ceil(outerBox.pageNum / 2)
 						}
-						if(i.isFix){
-							delete i.isFix
+						outerBox.index = outerIndex
+						// 如果是填空题或者问答题的大框 则需要根据小框把大框的位置坐标系 算出来
+						if((outerBox.type === 3 || outerBox.type === 4) && outerBox.points.length){
+							outerBox.count = outerBox.points.length
+							let firstChildPos = outerBox.points[0].pos
+							let lastChildPos = outerBox.points[outerBox.points.length - 1].pos
+							// 外框的四个点坐标 就是对应的 第一个的前两个和最后一个的后两个
+							outerBox.pos = [firstChildPos[0],firstChildPos[1],lastChildPos[2],lastChildPos[3]]
 						}
 					})
-					console.log(configParams.infoPos)
+					configParams.contents = this._.cloneDeep(configParams.newContents)
 					let curCode = paperInfo.examCode || paperInfo.code
 					let curScope = paperInfo.examScope || paperInfo.scope
 					if (paperInfo.sheet && withId) {
@@ -426,12 +484,12 @@
 					configParams.pageWidth = Number(configParams.pageWidth.toFixed())
 					configParams.pageCount = this.$store.state.answerSheet.pages
 					configParams.itemCount = this.$store.state.answerSheet.paperItem.item.length
-					// configParams.code = curCode.replace('Paper-','')
 					configParams.code = curCode.replace('Paper-', '').replace('Exam-', '') //如果是评测修改code会有问题
 					configParams.school = curScope === 'school' ? this.$store.state.userInfo.schoolCode : ''
 					configParams.scope = curScope
 					configParams.creatorId = this.$store.state.userInfo.TEAMModelId
-					console.log('答题卡数据参数', configParams)
+					delete configParams.newContents
+					console.error('答题卡数据参数', configParams)
 					// r(configParams)
 					/**
 					 * 这里有参数调整 liqk
@@ -698,7 +756,36 @@
 			width: 50px;
 		}
 	}
-
+	
+	
+	.pdf-modal{
+		.pdf-wrap{
+			display: flex;
+			align-items: center;
+			justify-content: space-around;
+			
+			.a4{
+				padding: 60px 40px;
+				border: 2px solid #C0C0C0;
+				border-radius: 4px;
+				cursor:pointer;
+			}
+			
+			.a3{
+				padding: 60px 80px;
+				border: 2px solid #C0C0C0;
+				border-radius: 4px;
+				cursor:pointer;
+			}
+			
+			.mode-active{
+				background: #53c6ff;
+				color:#fff;
+				font-size:14px;
+			}
+		}
+	}
+	
 	.sheet-groups {
 		position: absolute;
 		top: 280px;

+ 2 - 1
TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue

@@ -543,7 +543,8 @@
 						let sasData = {
 							sas: '?' + this.$store.state.user.osblob_sas,
 							name: 'teammodelos',
-							url: s.split(s.substring(s.lastIndexOf('/')))[0]
+							// url: s.split(s.substring(s.lastIndexOf('/')))[0]
+							url: this.$evTools.getBlobHost(s)
 						}
 						//初始化Blob
 						let containerClient = new blobTool(

+ 15 - 11
TEAMModelOS/ClientApp/src/view/resource/SourceCenter.vue

@@ -20,7 +20,7 @@
                         <span class="delete-source-icon" @click.stop="delResource(index)" v-if="isArea">
                             <Icon type="md-close" class="add-member-icon" />
                         </span>
-                        <div class="source-img" :style="{backgroundImage: `url(${item.type == 'link' ? item.thum : item.thum + '?' + areaSas})`}"></div>
+                        <div class="source-img" :style="{backgroundImage: `url(${item.type == 'private' ? item.thum + '?' + areaSas : item.thum})`}"></div>
                         <p class="img-text">
                             <span>主题:</span>
                             {{item.name}}
@@ -66,7 +66,7 @@
                     <Input v-model="resInfo.url" placeholder="请输入资源链接" />
                 </FormItem>
                 <FormItem label="附件" prop="blob" v-else>
-                    <Upload type="drag" :disabled="uploading"  action=""  show-upload-list :before-upload="customUpload" v-show="!file" :format="['mp4']" :on-format-error="handleFormatError">
+                    <Upload type="drag" :disabled="uploading" action="" show-upload-list :before-upload="customUpload" v-show="!file" :format="['mp4']" :on-format-error="handleFormatError">
                         <div style="padding: 20px 0">
                             <img v-if="uploading" src="@/assets/loading/loading.svg" alt="" width="80">
                             <Icon v-else type="ios-cloud-upload" size="52" style="color: #3399ff"></Icon>
@@ -119,7 +119,7 @@ export default {
             }
         }
         return {
-            uploading:false,
+            uploading: false,
             file: '',
             resInfo: {
                 name: '',
@@ -210,7 +210,7 @@ export default {
                 err => {
                     this.$Message.error('上传失败')
                 }
-            ).finally(()=>{
+            ).finally(() => {
                 this.uploading = false
             })
             return false
@@ -299,13 +299,17 @@ export default {
             this.addTypeStatus = true
         },
         toDetailPage(index) {
-            this.$router.push({
-                name: this.isArea ? 'areaResDetail' : 'schoolResDetail',
-                params: {
-                    sourceInfo: this.allData.resource[this.tabIndex].links[index],
-                    sourceList: this.allData.resource[this.tabIndex].links
-                }
-            })
+            if (this.allData.resource[this.tabIndex].links[index].type == 'link') {
+                window.open(this.allData.resource[this.tabIndex].links[index].url)
+            } else {
+                this.$router.push({
+                    name: this.isArea ? 'areaResDetail' : 'schoolResDetail',
+                    params: {
+                        sourceInfo: this.allData.resource[this.tabIndex].links[index],
+                        sourceList: this.allData.resource[this.tabIndex].links
+                    }
+                })
+            }
         },
         search() {
 

+ 2 - 2
TEAMModelOS/ClientApp/src/view/resource/SourceDetail.vue

@@ -8,7 +8,7 @@
             <div class="literacy-block-box">
                 <div class="video-info-wrap">
                     <h1 class="video-title">{{sourceInfo.name}}</h1>
-                    <video :src="sourceInfo.type == 'link' ? sourceInfo.url : sourceInfo.url + '?' + areaSas " class="video-box" controls="controls" autoplay="autoplay"></video>
+                    <video :src="sourceInfo.type == 'private' ? sourceInfo.url + '?' + areaSas : sourceInfo.url" class="video-box" controls="controls" autoplay="autoplay"></video>
                     <p class="info-item">
                         <span class="info-label">报告人:</span>
                         <span>{{sourceInfo.author || '未填写'}}</span>
@@ -30,7 +30,7 @@
                     <div class="video-list-box">
                         <vuescroll>
                             <div class="video-item" v-for="(item,index) in sourceList" :key="index" @click="chooseCus(index)">
-                                <img :src="item.type == 'link' ? item.thum : item.thum + '?' + areaSas" class="video-poster">
+                                <img :src="item.type == 'private' ? item.thum + '?' + areaSas : item.thum" class="video-poster">
                                 <div style="margin-left:15px">
                                     <p class="video-attr-item">
                                         <span class="info-label">报告人:</span>

+ 12 - 1
TEAMModelOS/ClientApp/src/view/settings/SchoolMgmt.less

@@ -59,11 +59,22 @@
 						font-size: 12px;
 						background: @primaryColor;
 						padding: 2px 8px;
-						margin-left: 10px;
+						margin-right: 10px;
 						border-radius: 2px;
 						font-weight: 200;
 						color: white;
 					}
+
+					&-nos{
+						margin-left: 10px;
+						border-left: 1px solid #ccc;
+						display: inline-block;
+						height: 16px;
+						line-height: 12px;
+						padding: 2px 10px;
+						// border-radius: 15px;
+						// font-size: 12px;
+					}
 					
 					&-code{
 						margin: 5px 0;

+ 3 - 2
TEAMModelOS/ClientApp/src/view/settings/SchoolMgmt.vue

@@ -19,14 +19,15 @@
 							<div style="display: flex;flex-direction: column;margin-left: 10px;">
 								<span class="school-item-name">
 									<span>{{ item.name }}</span>
+									<span class="school-item-nos">{{ item.schoolId  }}</span>
+								</span>
+								<span class="school-item-code">
 									<span class="school-item-status"
 										:style='{ background:bgFilter(item.status) }'>{{ statusFilter(item.status) }}</span>
 									<span class="school-item-status" style="background-color: #008352;"
 										v-show="item.schoolId === teacherInfo.defaultschool">{{ $t('settings.defaultSchool')}}</span>
 									<span class="school-item-status" style="background-color: #f59a2a;"
 										v-show="item.schoolId === curSchool">{{ $t('settings.curSchool')}}</span>
-								</span>
-								<span class="school-item-code">{{ item.schoolId  }}
 									<span class="school-item-nums" v-if="item.status === 'request'">
 										{{ getTime(item.time) }} {{ $t('settings.joinStatus')}}
 									</span>

+ 7 - 8
TEAMModelOS/ClientApp/src/view/student-account/stuMgt/AddStudent.vue

@@ -203,23 +203,22 @@ export default {
             }
         }
         const validateSeatNo = (rule, value, callback) => {
-            let flag = (value == null || typeof value == 'undefined' || value === '')
-            if (flag && (this.studentInfo.classId != null && typeof this.studentInfo.classId != 'undefined' && this.studentInfo.classId !== '')) {
-                callback(new Error('学生座位号不能为空'));
+            if (!value) {
+                callback(new Error(this.$t('stuAccount.setNoErr')));
             } else {
                 callback();
             }
         };
         const validateclassId = (rule, value, callback) => {
-            if (value === '' && (this.studentInfo.no != null && typeof this.studentInfo.no != 'undefined' && this.studentInfo.no !== '')) {
-                callback(new Error('班级资讯不能为空'));
+            if (!value) {
+                callback(new Error(this.$t('stuAccount.classErr')));
             } else {
                 callback()
             }
         };
         const validatePw = (rule, value, callback) => {
             if (this.bizType == 1 && value === '') {
-                callback(new Error('密码不能为空'));
+                callback(new Error(this.$t('stuAccount.pwErr')));
             } else {
                 callback()
             }
@@ -246,7 +245,7 @@ export default {
                     { validator: validatePw, trigger: 'blur' }
                 ],
                 name: [
-                    { required: true, message: '学生姓名不能为空', trigger: 'blur' }
+                    { required: true, message: this.$t('stuAccount.nameErr'), trigger: 'blur' }
                 ],
                 no: [
                     { validator: validateSeatNo, type: 'number', trigger: 'blur' }
@@ -327,7 +326,7 @@ export default {
                             return data
                         })
                         if (this.isRepeat(temp[0])) {
-                            this.$Message.error('請檢查 帳號資訊 或 座號重複 了。')
+                            this.$Message.error(this.$t('stuAccount.repeatErr'))
                             this.isLoading = false
                         } else {
                             apiData = temp

+ 2 - 0
TEAMModelOS/ClientApp/src/view/student-web/App.vue

@@ -68,9 +68,11 @@
                 </MenuItem> -->
                 <MenuItem name="4" to="/studentWeb/eventView" :title="$t('studentWeb.type.activity')">
                     <svg-icon icon-class="selflearning" class="tabIcon2" />
+                    <span v-show="MyNo != 4">{{ $t('studentWeb.type.activity') }}</span>
                 </MenuItem>
                 <MenuItem name="1" to="/studentWeb/homeView" :title="$t('studentWeb.type.home')">
                     <svg-icon icon-class="home" class="tabIcon3" />
+                    <span v-show="MyNo != 1">{{ $t('studentWeb.type.home') }}</span>
                 </MenuItem>
             </Menu>
         </div>

+ 3 - 3
TEAMModelOS/ClientApp/src/view/syllabus/Syllabus.vue

@@ -49,7 +49,7 @@
 					</div>
 				</div>
 				<vuescroll>
-					<EmptyData :top="100" v-if="!volumeList.length"></EmptyData>
+					<EmptyData  v-if="!volumeList.length"></EmptyData>
 					<div class="volume-list" v-else>
 						<div v-for="(volume,volumeIndex) in volumeList" :key="volumeIndex"
 							:class="['volume-item',activeVolumeIndex === volumeIndex ? 'volume-active' : '']"
@@ -99,7 +99,7 @@
 					</span>
 				</div>
 				<div class="syllabus-tree-box">
-					<EmptyData :top="-240" v-if="!treeOrigin.length"></EmptyData>
+					<EmptyData  v-if="!treeOrigin.length"></EmptyData>
 					<Tree ref="treeRef" :treeData="treeOrigin" :volume="curVolume"
 						:editable="hasSyllabusAuth || hasEditAuth(curNode)" @onNodeClick="onNodeClick"
 						@doShare="doShare" @addModifyId="addModifyId" v-else></Tree>
@@ -130,7 +130,7 @@
 					</span>
 				</div>
 				<div class="syllabus-tree-box">
-					<EmptyData :top="-203" v-if="curNode.rnodes && !curNode.rnodes.length"></EmptyData>
+					<EmptyData  v-if="curNode.rnodes && !curNode.rnodes.length"></EmptyData>
 					<div class="node-resource-box" v-else>
 						<div class="node-resource-item" v-for="(item,index) in curNode.rnodes" @click="onPreview(item)" :title="$t('teachContent.tips4')">
 							<img src="../../assets/source/image.png" v-if="item.type === 'image'" />

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

@@ -186,7 +186,7 @@ export default {
             split1: 0.2,
             curBarIndex: 1,
             taskList: [],
-            taskListShow:[],
+            taskListShow: [],
             curTaskIndex: 0,
             fullQuProg: false,
             markData: undefined,
@@ -198,10 +198,10 @@ export default {
     methods: {
         filterTask() {
             this.curTaskIndex = 0
-            this.taskListShow = this.taskList.filter(item=>{
+            this.taskListShow = this.taskList.filter(item => {
                 return item.progress == this.filter.status && (item.type == this.filter.type || !this.filter.type)
             })
-            if(this.taskListShow.length){
+            if (this.taskListShow.length) {
                 this.findTaskData()
             }
         },
@@ -321,6 +321,12 @@ export default {
         * childIndex 非必传
         */
         async toByQuView(data) {
+            // 批量阅卷路由(开发中,暂未完成)
+            // this.$router.push({
+            //     name: 'ByQu2'
+            // })
+            // return
+
             if (this.taskList[this.curTaskIndex].progress == 'pending') {
                 this.$Message.warning(this.$t('task.pendingTips'))
                 return
@@ -402,7 +408,7 @@ export default {
                         this.curTaskIndex = ch || 0
                         // if (this.taskList.length > 0) {
                         //     let type = this.taskList[this.curTaskIndex].type
-                            
+
                         // }
                         this.filterTask()
                     } else {
@@ -421,7 +427,8 @@ export default {
                 id: this.taskListShow[this.curTaskIndex].cid,
                 subjectId: this.taskListShow[this.curTaskIndex].subject,
                 tmdId: this.$store.state.userInfo.TEAMModelId,
-                type: this.taskListShow[this.curTaskIndex].type
+                type: this.taskListShow[this.curTaskIndex].type,
+                count: this.taskListShow[this.curTaskIndex].count
             }
             this.$api.mark.FindTeaData(requestData).then(
                 async res => {

+ 206 - 0
TEAMModelOS/ClientApp/src/view/task/mark/ByQu2.vue

@@ -0,0 +1,206 @@
+<template>
+    <div class="by-qu-container">
+        <div class="answer-box">
+            <div class="answer-info">
+                <span>当前题号:9-1</span>
+                <span>题目配分:{{quScore}}</span>
+                <span class="actoin-btn" @click="quitMark">
+                    <Icon type="ios-log-out" />
+                    退出阅卷
+                </span>
+            </div>
+            <vuescroll>
+                <div class="answer-list">
+                    <div class="answer-item" v-for="(item,index) in students" :key="item" @click="selectStudent(item)" @contextmenu.prevent="setWrong(item)">
+                        <img class="answer-img" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fm.wendangwang.com%2Fpic%2F861ba221ab39401c9c3c1960%2F1-424-png_6_0_0_98_294_609_204_829.259_1148.22-1267-0-0-1267.jpg&refer=http%3A%2F%2Fm.wendangwang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638603555&t=4baedbfe483009520eb4f2bedfc7e6ff" alt="">
+                        <Icon v-show="right.includes(item)" class="mark-tag" type="md-checkmark" />
+                        <Icon v-show="wrong.includes(item)" class="mark-tag" type="md-close" />
+                        <Icon v-show="half.includes(item)" class="mark-tag" custom="iconfont icon-half-right" />
+                        <div class="score-input-box" @click.stop>
+                            <InputNumber size="large" :max="quScore" :min="1" v-model="score[index]" style="width:60px"></InputNumber>
+                        </div>
+                    </div>
+                </div>
+            </vuescroll>
+        </div>
+        <div class="tool-box">
+            <p>操作类型:</p>
+            <RadioGroup v-model="action">
+                <Radio label="right" class="action-item">
+                    <span>打勾(给满分)</span>
+                </Radio>
+                <Radio label="half" class="action-item">
+                    <span>半勾(给一半分数)</span>
+                </Radio>
+                <Radio label="wrong" class="action-item">
+                    <span>打叉(给零分)</span>
+                </Radio>
+            </RadioGroup>
+            <Button type="primary" long class="save-btn">保存打分</Button>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            quScore: 12,
+            score: [null, null, null, null, null, null, null, null, null, null, null, null, null],
+            students: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
+            right: [],
+            wrong: [],
+            half: [],
+            action: 'right'
+        }
+    },
+    methods: {
+        quitMark() {
+            this.$router.go(-1)
+        },
+        setWrong(student) {
+            let index = this.wrong.findIndex(item => student === item)
+            if (index > -1) {
+                this.wrong.splice(index, 1)
+                this.$set(this.score, student, null)
+            } else {
+                this.wrong.push(student)
+                this.$set(this.score, student, 0)
+            }
+
+            //取消状态
+            let checkIndex = this.right.findIndex(item => student === item)
+            if (checkIndex > -1) this.right.splice(checkIndex, 1)
+            let checkIndex1 = this.half.findIndex(item => student === item)
+            if (checkIndex1 > -1) this.half.splice(checkIndex1, 1)
+        },
+        selectStudent(student) {
+            let dataArr, score
+            if (this.action == 'right') {
+                dataArr = this.right
+                score = this.quScore
+            } else if (this.action === 'wrong') {
+                dataArr = this.wrong
+                score = 0
+            } else if (this.action === 'half') {
+                dataArr = this.half
+                score = this.quScore / 2
+            }
+            let index = dataArr.findIndex(item => student === item)
+            if (index > -1) {
+                dataArr.splice(index, 1)
+                this.$set(this.score, student, null)
+            } else {
+                dataArr.push(student)
+                this.$set(this.score, student, score)
+            }
+
+            //取消状态
+            if (this.action != 'right') {
+                let checkIndex = this.right.findIndex(item => student === item)
+                if (checkIndex > -1) this.right.splice(checkIndex, 1)
+            }
+            if (this.action != 'half') {
+                let checkIndex = this.half.findIndex(item => student === item)
+                if (checkIndex > -1) this.half.splice(checkIndex, 1)
+            }
+            if (this.action != 'wrong') {
+                let checkIndex = this.wrong.findIndex(item => student === item)
+                if (checkIndex > -1) this.wrong.splice(checkIndex, 1)
+            }
+        }
+    },
+    mounted() {
+
+    }
+}
+</script>
+<style lang="less" scoped>
+.actoin-btn{
+    float: right;
+    cursor: pointer;
+}
+.action-item {
+    display: block;
+    margin-top: 8px;
+}
+.quit-mark {
+    cursor: pointer;
+    color: #1cc0f3;
+    user-select: none;
+}
+.score-input-box {
+    position: absolute;
+    left: 5px;
+    top: 5px;
+    // display: none;
+}
+.by-qu-container {
+    width: 100%;
+    height: 100%;
+    display: flex;
+}
+.answer-box {
+    width: ~"calc(100% - 300px)";
+    border-right: 1px solid var(--border-color);
+}
+.tool-box {
+    width: 300px;
+    padding: 15px 15px;
+}
+.answer-info {
+    height: 45px;
+    line-height: 45px;
+    padding-left: 15px;
+    box-shadow: 0 2px 5px #e9e9e9;
+    background-color: #fff;
+    span {
+        margin-right: 30px;
+    }
+}
+.answer-list {
+    margin-top: 15px;
+    display: flex;
+    width: 100%;
+    flex-wrap: wrap;
+    margin-bottom: 45px;
+}
+.answer-item {
+    margin-left: 15px;
+    margin-right: 20px;
+    margin-bottom: 20px;
+    box-shadow: 0 2px 5px #e9e9e9;
+    padding: 5px;
+    width: ~"calc(50% - 40px)";
+    position: relative;
+    &:hover .score-input-box {
+        display: block;
+    }
+    .answer-img {
+        width: 100%;
+    }
+    .mark-tag {
+        position: absolute;
+        right: 20px;
+        bottom: 20px;
+        font-size: 80px;
+        color: #d81e06;
+    }
+}
+.save-btn {
+    margin-top: 30px;
+}
+</style>
+<style lang="less">
+.score-input-box {
+    .ivu-input-number {
+        border-color: red;
+        background: rgba(255, 255, 255, 0.8);
+    }
+    .ivu-input-number-input {
+        color: red;
+        font-size: 20px;
+        font-weight: 600;
+        background: transparent;
+    }
+}
+</style>

+ 11 - 16
TEAMModelOS/ClientApp/src/view/task/mark/ByStu.vue

@@ -2,10 +2,7 @@
     <div class="mark-area">
         <!-- 头部基础信息 -->
         <div class="mark-header" v-show="!isComplete">
-            <span class="quit-marking-text">
-                <Icon type="ios-arrow-back" class="quit-marking-icon" :title="$t('learnActivity.mark.quit')" @click="quit" />
-            </span>
-            <span class="info-label">{{$t('learnActivity.mark.examName')}}</span>
+            <span class="info-label" style="margin-left:50px">{{$t('learnActivity.mark.examName')}}</span>
             <span class="info-value mark-info">{{taskInfo.name}}</span>
             <span class="info-label">{{$t('learnActivity.mark.reviewType')}}</span>
             <span class="info-value mark-info">{{$t('learnActivity.mark.byStu')}}</span>
@@ -19,13 +16,17 @@
                     {{$t('learnActivity.mark.toggleStu')}}
                 </span>
                 <span class="action-btn" @click="viewOriginal">
-                    <Icon type="md-eye"  class="action-btn-icon"/>
+                    <Icon type="md-eye" class="action-btn-icon" />
                     {{$t('learnActivity.score.viewOrigin')}}
                 </span>
                 <span class="action-btn" @click="errStatus = true" v-show="!quNoList[quIndex].err">
                     <Icon custom="iconfont icon-exception" class="action-btn-icon" />
                     {{$t('learnActivity.mark.exception')}}
                 </span>
+                <span class="action-btn" @click="quit">
+                    <Icon type="ios-log-out" :title="$t('learnActivity.mark.quit')" />
+                    {{$t('learnActivity.mark.quit')}}
+                </span>
             </div>
         </div>
         <div class="mark-main" v-show="!isComplete">
@@ -166,8 +167,8 @@ export default {
     },
     data() {
         return {
-            originalStatus:false,
-            sourceList:[],
+            originalStatus: false,
+            sourceList: [],
             errText: '',
             isComplete: false,
             loading: true,
@@ -608,7 +609,7 @@ export default {
         quScoreArr() {
             let score = parseInt(this.quScore[this.quIndex] || 10)
             let arr = Array.from(new Array(score + 1).keys())
-            if(this.quScore[this.quIndex] && this.quScore[this.quIndex] != score){
+            if (this.quScore[this.quIndex] && this.quScore[this.quIndex] != score) {
                 arr.push(this.quScore[this.quIndex])
             }
             return arr
@@ -751,16 +752,10 @@ export default {
     width: 850px;
     background: #f5f5f5;
 }
-.quit-marking-icon {
-    display: inline-block;
-    font-size: 18px;
-    width: 40px;
-    text-align: center;
-    cursor: pointer;
-    color: black;
-}
 .quit-marking-text {
     margin-right: 15px;
+    cursor: pointer;
+    margin-left: 15px;
 }
 .expression-box {
     max-width: 300px;

+ 282 - 259
TEAMModelOS/Controllers/Third/ScController.cs

@@ -105,7 +105,7 @@ namespace TEAMModelOS.Controllers.Third
             GetProjectInfoByTrainComID.code = Code;
             GetProjectInfoByTrainComID.title = "5.3.1.1获取项目列表";
 
-            /*
+          
             // 5.3.1.2获取学员名单
             Code = "GetTeachersListByProject";
             parameterMap = new Dictionary<string, object>();
@@ -141,45 +141,52 @@ namespace TEAMModelOS.Controllers.Third
             GetDiagnosisListByProject_V2.code = Code;
             GetDiagnosisListByProject_V2.title = "5.3.1.3通过项目编号获取学员测评能力项V2";
 
-
+            ScsResult UpdateTeacherSituation = null;
             // 5.3.1.4学员培训基本情况回写
-            Code = "UpdateTeacherSituation";
-            parameterMap = new Dictionary<string, object>();
-            parameterMap.Add("TrainComID", trainComID);
-            parameterMap.Add("PXID", "23");
-            parameterMap.Add("TID", "145504");
-            parameterMap.Add("TeacherName", "柏成伟");
-            parameterMap.Add("CourseHour", "50");
-            parameterMap.Add("ResearchText", "学习成果描述,字符长度<=300");
-            parameterMap.Add("ComPassed", "2");//0、未认定  1、合格  2、优秀  3、不合格  4、其他
-            ScsResult UpdateTeacherSituation = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
-            UpdateTeacherSituation.code = Code;
-            UpdateTeacherSituation.title = "5.3.1.4学员培训基本情况回写";
-
-
-            // 5.3.1.5学员能力点测评结果回写
-            Code = "UpdateTeacherDiagnosis";
-            parameterMap = new Dictionary<string, object>();
-            parameterMap.Add("TrainComID", trainComID);
-            parameterMap.Add("PXID", "65314");
-            parameterMap.Add("TID", "17542");
-            parameterMap.Add("DiagnosisNum", "A3");
-            //0"未认定", 1"合格", 2"优秀", 3"不合格"
-            parameterMap.Add("zpresult", "1");
-            parameterMap.Add("hpresult", "1");
-            parameterMap.Add("xzpresult", "1");
-            List<Dictionary<string, string>> pfilesA = new List<Dictionary<string, string>>();
-            parameterMap.Add("pfiles", pfilesA);
-            Dictionary<string, string> pfileMapA = new Dictionary<string, string>();
-            pfileMapA.Add("url", "https://scnltsfiles.scedu.com.cn/upload/infofj/202104011628463774.pdf");
-            pfileMapA.Add("fileName", "XXX.pdf");
-            pfileMapA.Add("fileSize", "247767");
-            pfileMapA.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
-            pfileMapA.Add("fileType", "pdf");
-            pfilesA.Add(pfileMapA);
-            ScsResult UpdateTeacherDiagnosis = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
-            UpdateTeacherDiagnosis.code = Code;
-            UpdateTeacherDiagnosis.title = "5.3.1.5学员能力点测评结果回写";
+            try {
+                Code = "UpdateTeacherSituation";
+                parameterMap = new Dictionary<string, object>();
+                parameterMap.Add("TrainComID", trainComID);
+                parameterMap.Add("PXID", "23");
+                parameterMap.Add("TID", "145504");
+                parameterMap.Add("TeacherName", "柏成伟");
+                parameterMap.Add("CourseHour", "50");
+                parameterMap.Add("ResearchText", "学习成果描述,字符长度<=300");
+                parameterMap.Add("ComPassed", "2");//0、未认定  1、合格  2、优秀  3、不合格  4、其他
+                UpdateTeacherSituation = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+                UpdateTeacherSituation.code = Code;
+                UpdateTeacherSituation.title = "5.3.1.4学员培训基本情况回写";
+            } catch (Exception ex) { }
+            ScsResult UpdateTeacherDiagnosis = null;
+            try
+            {
+
+                // 5.3.1.5学员能力点测评结果回写
+                Code = "UpdateTeacherDiagnosis";
+                parameterMap = new Dictionary<string, object>();
+                parameterMap.Add("TrainComID", trainComID);
+                parameterMap.Add("PXID", "65314");
+                parameterMap.Add("TID", "17542");
+                parameterMap.Add("DiagnosisNum", "A3");
+                //0"未认定", 1"合格", 2"优秀", 3"不合格"
+                parameterMap.Add("zpresult", "1");
+                parameterMap.Add("hpresult", "1");
+                parameterMap.Add("xzpresult", "1");
+                List<Dictionary<string, string>> pfilesA = new List<Dictionary<string, string>>();
+                parameterMap.Add("pfiles", pfilesA);
+                Dictionary<string, string> pfileMapA = new Dictionary<string, string>();
+                pfileMapA.Add("url", "https://scnltsfiles.scedu.com.cn/upload/infofj/202104011628463774.pdf");
+                pfileMapA.Add("fileName", "XXX.pdf");
+                pfileMapA.Add("fileSize", "247767");
+                pfileMapA.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
+                pfileMapA.Add("fileType", "pdf");
+                pfilesA.Add(pfileMapA);
+                UpdateTeacherDiagnosis = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+                UpdateTeacherDiagnosis.code = Code;
+                UpdateTeacherDiagnosis.title = "5.3.1.5学员能力点测评结果回写";
+            }
+            catch (Exception ex) { 
+            }
 
 
             // 5.3.1.6获取能力测评体系字典值数据
@@ -243,238 +250,254 @@ namespace TEAMModelOS.Controllers.Third
             GetSingleTeacherByProject.code = Code;
             GetSingleTeacherByProject.title = "5.3.1.11获取跳转学员信息";
 
-
-            // 5.3.1.12学员培训基本情况批量回写
-            Code = "UpdateTeacherListSituation";
+            ScsResult UpdateTeacherListSituation = null;
             Dictionary<string, object> parameterContent = new Dictionary<string, object>();
             List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
-            parameterContent.Add("TrainComID", trainComID);
-            parameterContent.Add("List", list);
-            // {"TrainComID":"39","List":[{"ResearchText":"","ComPassed":1,"PXID":"35455","CourseHour":"50.0","TID":"411105","TeacherName":"付绍令"}]}
-            {
-                Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
-
-                parameterMapData.Add("PXID", "23");
-                parameterMapData.Add("TID", "145504");
-                parameterMapData.Add("TeacherName", "柏成伟");
-                parameterMapData.Add("CourseHour", "50");
-                parameterMapData.Add("ResearchText", "学习成果描述,字符长度<=300");
-                parameterMapData.Add("ComPassed", "2");//0、未认定  1、合格  2、优秀  3、不合格  4、其他
-                list.Add(parameterMapData);
-                parameterMapData = new Dictionary<string, object>();
-
-                parameterMapData.Add("PXID", "23");
-                parameterMapData.Add("TID", "145504");
-                parameterMapData.Add("TeacherName", "柏成伟");
-                parameterMapData.Add("CourseHour", "50");
-                parameterMapData.Add("ResearchText", "学习成果描述,字符长度<=300");
-                parameterMapData.Add("ComPassed", "2");//0、未认定  1、合格  2、优秀  3、不合格  4、其他
-                list.Add(parameterMapData);
-                parameterMapData = new Dictionary<string, object>();
-
-                parameterMapData.Add("PXID", "22");
-                parameterMapData.Add("TID", "21348");
-                parameterMapData.Add("TeacherName", "邓泽燕");
-                parameterMapData.Add("CourseHour", "50");
-                parameterMapData.Add("ResearchText", "学习成果描述,字符长度<=300");
-                parameterMapData.Add("ComPassed", "2");//0、未认定  1、合格  2、优秀  3、不合格  4、其他
-                list.Add(parameterMapData);
-                parameterMapData = new Dictionary<string, object>();
-                parameterMapData.Add("PXID", "35546");
-                parameterMapData.Add("TID", "411182");
-                parameterMapData.Add("TeacherName", "刘晓莉");
-                parameterMapData.Add("CourseHour", "50");
-                parameterMapData.Add("ResearchText", "");
-                parameterMapData.Add("ComPassed", "1");//0、未认定  1、合格  2、优秀  3、不合格  4、其他
-                list.Add(parameterMapData);
+            try
+            { // 5.3.1.12学员培训基本情况批量回写
+                Code = "UpdateTeacherListSituation";
+              
+              
+                parameterContent.Add("TrainComID", trainComID);
+                parameterContent.Add("List", list);
+                // {"TrainComID":"39","List":[{"ResearchText":"","ComPassed":1,"PXID":"35455","CourseHour":"50.0","TID":"411105","TeacherName":"付绍令"}]}
+                {
+                    Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
+
+                    parameterMapData.Add("PXID", "23");
+                    parameterMapData.Add("TID", "145504");
+                    parameterMapData.Add("TeacherName", "柏成伟");
+                    parameterMapData.Add("CourseHour", "50");
+                    parameterMapData.Add("ResearchText", "学习成果描述,字符长度<=300");
+                    parameterMapData.Add("ComPassed", "2");//0、未认定  1、合格  2、优秀  3、不合格  4、其他
+                    list.Add(parameterMapData);
+                    parameterMapData = new Dictionary<string, object>();
+
+                    parameterMapData.Add("PXID", "23");
+                    parameterMapData.Add("TID", "145504");
+                    parameterMapData.Add("TeacherName", "柏成伟");
+                    parameterMapData.Add("CourseHour", "50");
+                    parameterMapData.Add("ResearchText", "学习成果描述,字符长度<=300");
+                    parameterMapData.Add("ComPassed", "2");//0、未认定  1、合格  2、优秀  3、不合格  4、其他
+                    list.Add(parameterMapData);
+                    parameterMapData = new Dictionary<string, object>();
+
+                    parameterMapData.Add("PXID", "22");
+                    parameterMapData.Add("TID", "21348");
+                    parameterMapData.Add("TeacherName", "邓泽燕");
+                    parameterMapData.Add("CourseHour", "50");
+                    parameterMapData.Add("ResearchText", "学习成果描述,字符长度<=300");
+                    parameterMapData.Add("ComPassed", "2");//0、未认定  1、合格  2、优秀  3、不合格  4、其他
+                    list.Add(parameterMapData);
+                    parameterMapData = new Dictionary<string, object>();
+                    parameterMapData.Add("PXID", "35546");
+                    parameterMapData.Add("TID", "411182");
+                    parameterMapData.Add("TeacherName", "刘晓莉");
+                    parameterMapData.Add("CourseHour", "50");
+                    parameterMapData.Add("ResearchText", "");
+                    parameterMapData.Add("ComPassed", "1");//0、未认定  1、合格  2、优秀  3、不合格  4、其他
+                    list.Add(parameterMapData);
+                }
+                UpdateTeacherListSituation = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
+                UpdateTeacherListSituation.code = Code;
+                UpdateTeacherListSituation.title = "5.3.1.12学员培训基本情况批量回写";
             }
-            ScsResult UpdateTeacherListSituation = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
-            UpdateTeacherListSituation.code = Code;
-            UpdateTeacherListSituation.title = "5.3.1.12学员培训基本情况批量回写";
-
-
-
-            // 5.3.1.13学员能力点测评结果批量回写
-            Code = "UpdateTeacherListDiagnosis";
-            parameterContent = new Dictionary<string, object>();
-            list = new List<Dictionary<string, object>>();
-            parameterContent.Add("TrainComID", trainComID);
-            parameterContent.Add("List", list);
-            {
-                Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
+            catch (Exception ex) { }
+
+            ScsResult UpdateTeacherListDiagnosis = null;
+            try
+            { // 5.3.1.13学员能力点测评结果批量回写
+                Code = "UpdateTeacherListDiagnosis";
+                parameterContent = new Dictionary<string, object>();
+                list = new List<Dictionary<string, object>>();
+                parameterContent.Add("TrainComID", trainComID);
+                parameterContent.Add("List", list);
+                {
+                    Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
+
+                    parameterMapData.Add("PXID", "3079");
+                    parameterMapData.Add("TID", "14597");
+                    parameterMapData.Add("DiagnosisNum", "A6");
+                    //0"未认定", 1"合格", 2"优秀", 3"不合格"
+                    parameterMapData.Add("zpresult", "1");
+                    parameterMapData.Add("hpresult", "2");
+                    parameterMapData.Add("xzpresult", "2");
+                    List<Dictionary<string, object>> pfiles = new List<Dictionary<string, object>>();
+                    parameterMapData.Add("pfiles", pfiles);
+                    Dictionary<string, object> pfileMap = new Dictionary<string, object>();
+                    pfileMap.Add("url", "https://srt-read-online.3ren.cn/basebusiness/material/20210422/1619055398463iE97VWe36i001.mp4");
+                    pfileMap.Add("fileName", "697a58c2375f7a031456c893e1e1860c.mp4");
+                    pfileMap.Add("fileSize", "17036168");
+                    pfileMap.Add("md5", "");
+                    pfileMap.Add("fileType", "video");
+                    pfiles.Add(pfileMap);
+
+                    list.Add(parameterMapData);
+
+                    pfileMap = new Dictionary<string, object>();
+                    pfileMap.Add("url", "https://srt-read-online.3ren.cn/basebusiness/material/20210422/1619055446704gbKuNF8eas001.pdf");
+                    pfileMap.Add("fileName", "A6技术支持的课堂反思.pdf");
+                    pfileMap.Add("fileSize", "32192");
+                    pfileMap.Add("md5", "");
+                    pfileMap.Add("fileType", "pdf");
+                    pfiles.Add(pfileMap);
+
+                    list.Add(parameterMapData);
+                }
 
-                parameterMapData.Add("PXID", "3079");
-                parameterMapData.Add("TID", "14597");
-                parameterMapData.Add("DiagnosisNum", "A6");
-                //0"未认定", 1"合格", 2"优秀", 3"不合格"
-                parameterMapData.Add("zpresult", "1");
-                parameterMapData.Add("hpresult", "2");
-                parameterMapData.Add("xzpresult", "2");
-                List<Dictionary<string, object>> pfiles = new List<Dictionary<string, object>>();
-                parameterMapData.Add("pfiles", pfiles);
-                Dictionary<string, object> pfileMap = new Dictionary<string, object>();
-                pfileMap.Add("url", "https://srt-read-online.3ren.cn/basebusiness/material/20210422/1619055398463iE97VWe36i001.mp4");
-                pfileMap.Add("fileName", "697a58c2375f7a031456c893e1e1860c.mp4");
-                pfileMap.Add("fileSize", "17036168");
-                pfileMap.Add("md5", "");
-                pfileMap.Add("fileType", "video");
-                pfiles.Add(pfileMap);
-
-                list.Add(parameterMapData);
-
-                pfileMap = new Dictionary<string, object>();
-                pfileMap.Add("url", "https://srt-read-online.3ren.cn/basebusiness/material/20210422/1619055446704gbKuNF8eas001.pdf");
-                pfileMap.Add("fileName", "A6技术支持的课堂反思.pdf");
-                pfileMap.Add("fileSize", "32192");
-                pfileMap.Add("md5", "");
-                pfileMap.Add("fileType", "pdf");
-                pfiles.Add(pfileMap);
-
-                list.Add(parameterMapData);
+                {
+                    Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
+
+                    parameterMapData.Add("PXID", "3062");
+                    parameterMapData.Add("TID", "401268");
+                    parameterMapData.Add("DiagnosisNum", "A1");
+                    //0"未认定", 1"合格", 2"优秀", 3"不合格"
+                    parameterMapData.Add("zpresult", "1");
+                    parameterMapData.Add("hpresult", "2");
+                    parameterMapData.Add("xzpresult", "2");
+                    List<Dictionary<string, object>> pfiles = new List<Dictionary<string, object>>();
+                    parameterMapData.Add("pfiles", pfiles);
+                    Dictionary<string, object> pfileMap = new Dictionary<string, object>();
+                    pfileMap.Add("url", "https://srt-read-online.3ren.cn/basebusiness/material/20210422/1619058650000bphKFbDVSa001.pdf");
+                    pfileMap.Add("fileName", "学情分析.pdf");
+                    pfileMap.Add("fileSize", "94926");
+                    pfileMap.Add("md5", "");
+                    pfileMap.Add("fileType", "pdf");
+                    pfiles.Add(pfileMap);
+
+                    list.Add(parameterMapData);
+
+                    pfileMap = new Dictionary<string, object>();
+                    pfileMap.Add("url", "https://srt-read-online.3ren.cn/basebusiness/material/20210422/1619058698452gF19jmiuML001.mp4");
+                    pfileMap.Add("fileName", "种子萌发学情分析.mp4");
+                    pfileMap.Add("fileSize", "12692368");
+                    pfileMap.Add("md5", "");
+                    pfileMap.Add("fileType", "video");
+                    pfiles.Add(pfileMap);
+                    list.Add(parameterMapData);
+                }
+                 UpdateTeacherListDiagnosis = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
+                UpdateTeacherListDiagnosis.code = Code;
+                UpdateTeacherListDiagnosis.title = "5.3.1.13学员能力点测评结果批量回写";
             }
-
-            {
-                Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
-
-                parameterMapData.Add("PXID", "3062");
-                parameterMapData.Add("TID", "401268");
-                parameterMapData.Add("DiagnosisNum", "A1");
-                //0"未认定", 1"合格", 2"优秀", 3"不合格"
-                parameterMapData.Add("zpresult", "1");
-                parameterMapData.Add("hpresult", "2");
-                parameterMapData.Add("xzpresult", "2");
-                List<Dictionary<string, object>> pfiles = new List<Dictionary<string, object>>();
-                parameterMapData.Add("pfiles", pfiles);
-                Dictionary<string, object> pfileMap = new Dictionary<string, object>();
-                pfileMap.Add("url", "https://srt-read-online.3ren.cn/basebusiness/material/20210422/1619058650000bphKFbDVSa001.pdf");
-                pfileMap.Add("fileName", "学情分析.pdf");
-                pfileMap.Add("fileSize", "94926");
-                pfileMap.Add("md5", "");
-                pfileMap.Add("fileType", "pdf");
-                pfiles.Add(pfileMap);
-
-                list.Add(parameterMapData);
-
-                pfileMap = new Dictionary<string, object>();
-                pfileMap.Add("url", "https://srt-read-online.3ren.cn/basebusiness/material/20210422/1619058698452gF19jmiuML001.mp4");
-                pfileMap.Add("fileName", "种子萌发学情分析.mp4");
-                pfileMap.Add("fileSize", "12692368");
-                pfileMap.Add("md5", "");
-                pfileMap.Add("fileType", "video");
-                pfiles.Add(pfileMap);
-                list.Add(parameterMapData);
+            catch (Exception ex) { 
             }
-            ScsResult UpdateTeacherListDiagnosis = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
-            UpdateTeacherListDiagnosis.code = Code;
-            UpdateTeacherListDiagnosis.title = "5.3.1.13学员能力点测评结果批量回写";
-
 
 
-
-            // 5.3.1.14学员校本研修PDF回写
-            Code = "UploadSBTARPDF";
-            parameterMap = new Dictionary<string, object>();
-            parameterMap.Add("TrainComID", trainComID);
-            parameterMap.Add("PXID", "16");
-            parameterMap.Add("TID", "16");
-
-            parameterMap.Add("url", "http://image1.cersp.com.cn/scpx/images/article/file/20190318/upload__51f98fc8_1697695ae73__7ffe_00001297.pdf");
-            parameterMap.Add("fileName", "XXX.pdf");
-            parameterMap.Add("fileSize", "247767");
-            parameterMap.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
-            parameterMap.Add("fileType", "pdf");
-            ScsResult UploadSBTARPDF = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
-            UploadSBTARPDF.code = Code;
-            UploadSBTARPDF.title = "5.3.1.14学员校本研修PDF回写";
-
-
-
-            // 5.3.1.15学员校本教研PDF批量回写
-            Code = "UploadSBTARPDFList";
-            parameterContent = new Dictionary<string, object>();
-            list = new List<Dictionary<string, object>>();
-            parameterContent.Add("TrainComID", trainComID);
-            parameterContent.Add("List", list);
-            {
-                Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
-                parameterMapData.Add("PXID", "65309");
-                parameterMapData.Add("TID", "253940");
-                parameterMapData.Add("url", "https://scnltsfiles.scedu.com.cn/upload/infofj/202104011628463774.pdf");
-                parameterMapData.Add("fileName", "XXX.pdf");
-                parameterMapData.Add("fileSize", "247767");
-                parameterMapData.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
-                parameterMapData.Add("fileType", "pdf");
-                list.Add(parameterMapData);
+            ScsResult UploadSBTARPDF = null;
+            try
+            {   // 5.3.1.14学员校本研修PDF回写
+                Code = "UploadSBTARPDF";
+                parameterMap = new Dictionary<string, object>();
+                parameterMap.Add("TrainComID", trainComID);
+                parameterMap.Add("PXID", "16");
+                parameterMap.Add("TID", "16");
+
+                parameterMap.Add("url", "http://image1.cersp.com.cn/scpx/images/article/file/20190318/upload__51f98fc8_1697695ae73__7ffe_00001297.pdf");
+                parameterMap.Add("fileName", "XXX.pdf");
+                parameterMap.Add("fileSize", "247767");
+                parameterMap.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
+                parameterMap.Add("fileType", "pdf");
+                UploadSBTARPDF = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+                UploadSBTARPDF.code = Code;
+                UploadSBTARPDF.title = "5.3.1.14学员校本研修PDF回写";
             }
-            {
-                Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
-                parameterMapData.Add("PXID", "65306");
-                parameterMapData.Add("TID", "32393");
-                parameterMapData.Add("url", "https://scnltsfiles.scedu.com.cn/upload/infofj/202104011628463774.pdf");
-                parameterMapData.Add("fileName", "XXX.pdf");
-                parameterMapData.Add("fileSize", "247767");
-                parameterMapData.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
-                parameterMapData.Add("fileType", "pdf");
-                list.Add(parameterMapData);
+            catch (Exception ex) { 
             }
-            ScsResult UploadSBTARPDFList = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
-            UploadSBTARPDFList.code = Code;
-            UploadSBTARPDFList.title = "5.3.1.15学员校本教研PDF批量回写";
-
 
-
-            // 5.3.1.16学员课堂实录回写
-            Code = "UploadKTSL";
-            parameterMap = new Dictionary<string, object>();
-            parameterMap.Add("TrainComID", trainComID);
-            parameterMap.Add("PXID", "16");
-            parameterMap.Add("TID", "16");
-            parameterMap.Add("url", "https://xxx.mp4");
-            parameterMap.Add("url2", "https://xxx.mp4");
-            parameterMap.Add("fileName", "XXX.mp4");
-            parameterMap.Add("fileSize", "247767");
-            parameterMap.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
-            parameterMap.Add("fileType", "mp4");
-            ScsResult UploadKTSL = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
-            UploadKTSL.code = Code;
-            UploadKTSL.title = "5.3.1.16学员课堂实录回写";
-
-
-            //  5.3.1.17学员课堂实录批量回写
-            Code = "UploadKTSLList";
-            parameterContent = new Dictionary<string, object>();
-            list = new List<Dictionary<string, object>>();
-            parameterContent.Add("TrainComID", trainComID);
-            parameterContent.Add("List", list);
-            {
-                Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
-                parameterMapData.Add("PXID", "16");
-                parameterMapData.Add("TID", "16");
-                parameterMapData.Add("url", "https://xxx.mp4");
-                parameterMapData.Add("url2", "https://xxx.mp4");
-                parameterMapData.Add("fileName", "XXX.mp4");
-                parameterMapData.Add("fileSize", "247767");
-                parameterMapData.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
-                parameterMapData.Add("fileType", "mp4");
-                list.Add(parameterMapData);
+            ScsResult UploadSBTARPDFList = null;
+            try
+            { // 5.3.1.15学员校本教研PDF批量回写
+                Code = "UploadSBTARPDFList";
+                parameterContent = new Dictionary<string, object>();
+                list = new List<Dictionary<string, object>>();
+                parameterContent.Add("TrainComID", trainComID);
+                parameterContent.Add("List", list);
+                {
+                    Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
+                    parameterMapData.Add("PXID", "65309");
+                    parameterMapData.Add("TID", "253940");
+                    parameterMapData.Add("url", "https://scnltsfiles.scedu.com.cn/upload/infofj/202104011628463774.pdf");
+                    parameterMapData.Add("fileName", "XXX.pdf");
+                    parameterMapData.Add("fileSize", "247767");
+                    parameterMapData.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
+                    parameterMapData.Add("fileType", "pdf");
+                    list.Add(parameterMapData);
+                }
+                {
+                    Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
+                    parameterMapData.Add("PXID", "65306");
+                    parameterMapData.Add("TID", "32393");
+                    parameterMapData.Add("url", "https://scnltsfiles.scedu.com.cn/upload/infofj/202104011628463774.pdf");
+                    parameterMapData.Add("fileName", "XXX.pdf");
+                    parameterMapData.Add("fileSize", "247767");
+                    parameterMapData.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
+                    parameterMapData.Add("fileType", "pdf");
+                    list.Add(parameterMapData);
+                }
+                UploadSBTARPDFList = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
+                UploadSBTARPDFList.code = Code;
+                UploadSBTARPDFList.title = "5.3.1.15学员校本教研PDF批量回写";
             }
+            catch (Exception ex) { }
+            ScsResult UploadKTSL = null;
+            try
             {
-                Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
-                parameterMapData.Add("PXID", "16");
-                parameterMapData.Add("TID", "16");
-                parameterMapData.Add("url", "https://xxx.mp4");
-                parameterMapData.Add("url2", "https://xxx.mp4");
-                parameterMapData.Add("fileName", "XXX.mp4");
-                parameterMapData.Add("fileSize", "247767");
-                parameterMapData.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
-                parameterMapData.Add("fileType", "mp4");
-                list.Add(parameterMapData);
-            }
-            ScsResult UploadKTSLList = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
-            UploadKTSLList.code = Code;
-            UploadKTSLList.title = "5.3.1.17学员课堂实录批量回写";
-
+                // 5.3.1.16学员课堂实录回写
+                Code = "UploadKTSL";
+                parameterMap = new Dictionary<string, object>();
+                parameterMap.Add("TrainComID", trainComID);
+                parameterMap.Add("PXID", "16");
+                parameterMap.Add("TID", "16");
+                parameterMap.Add("url", "https://xxx.mp4");
+                parameterMap.Add("url2", "https://xxx.mp4");
+                parameterMap.Add("fileName", "XXX.mp4");
+                parameterMap.Add("fileSize", "247767");
+                parameterMap.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
+                parameterMap.Add("fileType", "mp4");
+                 UploadKTSL = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+                UploadKTSL.code = Code;
+                UploadKTSL.title = "5.3.1.16学员课堂实录回写";
+            } catch (Exception ex) { }
+            ScsResult UploadKTSLList = null;
+            try
+            {
+                //  5.3.1.17学员课堂实录批量回写
+                Code = "UploadKTSLList";
+                parameterContent = new Dictionary<string, object>();
+                list = new List<Dictionary<string, object>>();
+                parameterContent.Add("TrainComID", trainComID);
+                parameterContent.Add("List", list);
+                {
+                    Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
+                    parameterMapData.Add("PXID", "16");
+                    parameterMapData.Add("TID", "16");
+                    parameterMapData.Add("url", "https://xxx.mp4");
+                    parameterMapData.Add("url2", "https://xxx.mp4");
+                    parameterMapData.Add("fileName", "XXX.mp4");
+                    parameterMapData.Add("fileSize", "247767");
+                    parameterMapData.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
+                    parameterMapData.Add("fileType", "mp4");
+                    list.Add(parameterMapData);
+                }
+                {
+                    Dictionary<string, object> parameterMapData = new Dictionary<string, object>();
+                    parameterMapData.Add("PXID", "16");
+                    parameterMapData.Add("TID", "16");
+                    parameterMapData.Add("url", "https://xxx.mp4");
+                    parameterMapData.Add("url2", "https://xxx.mp4");
+                    parameterMapData.Add("fileName", "XXX.mp4");
+                    parameterMapData.Add("fileSize", "247767");
+                    parameterMapData.Add("md5", "9c3da8c5c07c2c660cd73c01f56d7fca");
+                    parameterMapData.Add("fileType", "mp4");
+                    list.Add(parameterMapData);
+                }
+                UploadKTSLList = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
+                UploadKTSLList.code = Code;
+                UploadKTSLList.title = "5.3.1.17学员课堂实录批量回写";
 
+            }
+            catch (Exception ex) { }
 
             // 5.3.1.18根据机构ID、项目ID、子项目ID返回学校列表
             Code = "GetSchoolList";
@@ -535,8 +558,8 @@ namespace TEAMModelOS.Controllers.Third
                 GetProjectDiagnosis,
                 GetSchoolDiagnosis
             });
-            */
-            return Ok(GetProjectInfoByTrainComID);
+            
+            //return Ok(GetProjectInfoByTrainComID);
         }
 
         public class ScsResult {

+ 4 - 4
TEAMModelOS/TEAMModelOS.csproj

@@ -37,9 +37,9 @@
     <SpaRoot>ClientApp\</SpaRoot>
     <DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
     <UserSecretsId>078b5d89-7d90-4f6a-88fc-7d96025990a8</UserSecretsId>
-    <Version>5.2111.5</Version>
-    <AssemblyVersion>5.2111.5.1</AssemblyVersion>
-    <FileVersion>5.2111.2.1</FileVersion>
+    <Version>5.2111.11</Version>
+    <AssemblyVersion>5.2111.11.1</AssemblyVersion>
+    <FileVersion>5.2111.11.1</FileVersion>
     <Description>TEAMModelOS(IES5)</Description>
     <PackageReleaseNotes>版本说明</PackageReleaseNotes>
   </PropertyGroup>
@@ -84,5 +84,5 @@
     </ItemGroup>
   </Target>
 
-  <ProjectExtensions><VisualStudio><UserProperties appsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
+  <ProjectExtensions><VisualStudio><UserProperties appsettings_1json__JsonSchema="" clientapp_4package_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
 </Project>

+ 12 - 12
TEAMModelOS/appsettings.Development.json

@@ -56,19 +56,19 @@
     }
   },
   "Third": {
-    //"scsyxpt": {
-    //  "passKey": "VgEQfEjwzfvFn8my", //机构安全码
-    //  "trainComID": "2065", //机构ID
-    //  "privateKey": "4DB15444DEEDBB28B718ACB09217B5FC", //机构 AES 密钥
-    //  "url": "http://testscts.scedu.com.cn/webservice/EduService.asmx/RequestService"
-    //  //"url": "https://scts.scedu.com.cn/webservice/EduService.asmx/RequestService" 
-    //},
     "scsyxpt": {
-      "passKey": "fst4clhyXqrhXblY", //机构安全码
-      "trainComID": "3069", //机构ID
-      "privateKey": "52C1C240E4BE086DD15DB10814E243E6", //机构 AES 密钥
-      //"url": "http://testscts.scedu.com.cn/webservice/EduService.asmx/RequestService"
-      "url": "https://scts.scedu.com.cn/webservice/EduService.asmx/RequestService"
+      "passKey": "VgEQfEjwzfvFn8my", //机构安全码
+      "trainComID": "2065", //机构ID 2065 65324
+      "privateKey": "4DB15444DEEDBB28B718ACB09217B5FC", //机构 AES 密钥
+      "url": "http://testscts.scedu.com.cn/webservice/EduService.asmx/RequestService"
+      //"url": "https://scts.scedu.com.cn/webservice/EduService.asmx/RequestService" 
     }
+    //"scsyxpt": {
+    //  "passKey": "fst4clhyXqrhXblY", //机构安全码
+    //  "trainComID": "3069", //机构ID
+    //  "privateKey": "52C1C240E4BE086DD15DB10814E243E6", //机构 AES 密钥
+    //  //"url": "http://testscts.scedu.com.cn/webservice/EduService.asmx/RequestService"
+    //  "url": "https://scts.scedu.com.cn/webservice/EduService.asmx/RequestService"
+    //}
   }
 }