Prechádzať zdrojové kódy

Merge branch 'develop5.0-tmd' of http://106.12.23.251:10000/TEAMMODEL/TEAMModelOS into develop5.0-tmd

liqk 3 rokov pred
rodič
commit
c079139c16
22 zmenil súbory, kde vykonal 716 pridanie a 242 odobranie
  1. 80 0
      TEAMModeBI/Controllers/AESHelper.cs
  2. 6 2
      TEAMModeBI/Program.cs
  3. 15 16
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseProgress.vue
  4. 6 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/ClassmateCommentPages.vue
  5. 4 3
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/Homework.vue
  6. 7 5
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue
  7. 2 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperTest.vue
  8. 4 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/QuesNaire.vue
  9. 4 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/Vote.vue
  10. 9 5
      TEAMModelOS/ClientApp/src/utils/evTools.js
  11. 3 2
      TEAMModelOS/ClientApp/src/utils/public.js
  12. 1 0
      TEAMModelOS/ClientApp/src/view/evaluation/bank/index.vue
  13. 4 2
      TEAMModelOS/ClientApp/src/view/jyzx/Question.vue
  14. 5 3
      TEAMModelOS/ClientApp/src/view/jyzx/Vote.vue
  15. 2 2
      TEAMModelOS/ClientApp/src/view/newsheet/BaseEditor.vue
  16. 1 0
      TEAMModelOS/ClientApp/src/view/newsheet/index.vue
  17. 80 0
      TEAMModelOS/Controllers/Third/Helpers/AESHelper.cs
  18. 413 1
      TEAMModelOS/Controllers/Third/ScController.cs
  19. 59 0
      TEAMModelOS/Controllers/Third/ScsApisService.cs
  20. 0 193
      TEAMModelOS/Controllers/Third/SsoController.cs
  21. 2 0
      TEAMModelOS/Startup.cs
  22. 9 0
      TEAMModelOS/appsettings.Development.json

+ 80 - 0
TEAMModeBI/Controllers/AESHelper.cs

@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TEAMModelOS.Controllers.Third.Helpers
+{
+    public class AESHelper
+    {
+
+        /// <summary>
+        /// 有密码的加密 
+        /// </summary>
+        /// <param name="toEncrypt">加密字符</param>
+        /// <param name="key">加密的密码</param>
+        /// <returns></returns>
+        public static string AESEncrypt(string toEncrypt, string key)
+        {
+            byte[] keyArray = hexStringTobyte(key);
+            byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
+            RijndaelManaged rDel = new RijndaelManaged();
+            rDel.KeySize = 128;
+            rDel.BlockSize = 128;
+            rDel.Key = keyArray;
+            rDel.Mode = CipherMode.ECB;
+            rDel.Padding = PaddingMode.PKCS7;
+            ICryptoTransform cTransform = rDel.CreateEncryptor();
+            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
+            return byteToHexString(resultArray);
+        }
+
+        /// <summary>
+        /// 解密
+        /// </summary>
+        /// <param name="toDecrypt">解密字符</param>
+        /// <param name="key">加密的密码</param>
+        /// <returns></returns>
+        public static string AESDecrypt(string toDecrypt, string key)
+        {
+            byte[] keyArray = hexStringTobyte(key);
+            byte[] dest = hexStringTobyte(toDecrypt);
+            RijndaelManaged rDel = new RijndaelManaged();
+            rDel.KeySize = 128;
+            rDel.BlockSize = 128;
+            rDel.Key = keyArray;
+            rDel.Mode = CipherMode.ECB;
+            rDel.Padding = PaddingMode.PKCS7;
+            ICryptoTransform cTransform = rDel.CreateDecryptor();
+            byte[] resultArray = cTransform.TransformFinalBlock(dest, 0, dest.Length);
+            return UTF8Encoding.UTF8.GetString(resultArray);
+        }
+
+
+        private static byte[] hexStringTobyte(String s)
+        {
+            if (string.IsNullOrEmpty(s)) return null;
+            s = s.ToLower();
+            int byteArrayLength = s.Length / 2;
+            byte[] b = new byte[byteArrayLength];
+            for (int i = 0; i < byteArrayLength; i++)
+            {
+                byte b0 = Convert.ToByte(s.Substring(i * 2, 2), 16);
+                b[i] = b0;
+            }
+            return b;
+        }
+
+        public static string byteToHexString(byte[] t)
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < t.Length; i++)
+            {
+                sb.Append(t[i].ToString("x").PadLeft(2, '0'));
+            }
+            return sb.ToString().ToUpper();
+        }
+    }
+}

+ 6 - 2
TEAMModeBI/Program.cs

@@ -4,18 +4,22 @@ using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Logging;
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
+using System.Net;
 using System.Threading.Tasks;
+using TEAMModelOS.Controllers.Third.Helpers;
+using TEAMModelOS.SDK.Extension;
+using System.Text;
 
 namespace TEAMModeBI
 {
     public class Program
-    {
+    {     
         public static void Main(string[] args)
         {
             CreateHostBuilder(args).Build().Run();
         }
-
         public static IHostBuilder CreateHostBuilder(string[] args) =>
             Host.CreateDefaultBuilder(args)
                 .ConfigureWebHostDefaults(webBuilder =>

+ 15 - 16
TEAMModelOS/ClientApp/src/components/questionnaire/BaseProgress.vue

@@ -75,14 +75,14 @@
 					},
 					polar: [{
 						center: ['50%', '50%'], //中心点位置
-						radius: '80%' //图形大小
+						radius: '88%' //图形大小
 					}],
 					series: [{
 							name: '小环',
 							type: 'gauge',
 							splitNumber: 0,
-							radius: '32%', //中间装饰环
-							center: ['50%', '50%'],
+							radius: '30%', //中间装饰环
+							center: ['30%', '30%'],
 							startAngle: 0,
 							endAngle: 359.9999,
 							axisLine: {
@@ -107,7 +107,7 @@
 							},
 							detail: {
 								show: true,
-								offsetCenter: ['0%', '-230%'],
+								offsetCenter: ['0%', '-210%'],
 								color: '#6c6c6c',
 								formatter: function(params) {
 									return that.$t('survey.questionaire.progress')
@@ -133,22 +133,21 @@
 							roundCap: true,
 							barWidth: 18, //大的占比环
 							itemStyle: {
-								normal: {
-									opacity: 1,
-									color: new that.$echarts.graphic.LinearGradient(0, 0, 1, 1, [{
-										offset: 0,
-										color: '#D0E5F6'
-									}, {
-										offset: 1,
-										color: '#70B1E7'
-									}])
-								}
-							},
+							    normal: {
+							        color: new this.$echarts.graphic.LinearGradient(0, 1, 0, 0, [{
+							            offset: 0,
+							            color: '#585fe1'
+							        }, {
+							            offset: 1,
+							            color: '#0ff'
+							        }]),
+							    }
+							}
 						},
 						{
 							type: 'pie',
 							name: '内层细圆环',
-							radius: ['50%', '30%'],
+							radius: ['50%', '40%'],
 							// radius: '50%',
 							startAngle: 90,
 							hoverAnimation: false,

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

@@ -65,7 +65,7 @@
                             <i-col :xs="24" :sm="24" :md="18" :lg="18">
                                 <div>
                                     <div>
-                                        <video v-if="nowStudentHw.content[currentdocPreview].type === 'video'" :id="'video' + index" :src="nowStudentHw.content[currentdocPreview].url" controls="controls" style="border-radius: 5px;max-height: 700px;max-width: 100%;" />
+                                        <video v-if="nowStudentHw.content[currentdocPreview].type === 'video'" :id="'video' + currentdocPreview" :src="nowStudentHw.content[currentdocPreview].url" controls="controls" style="border-radius: 5px;max-height: 700px;max-width: 100%;" />
                                         <img v-if="nowStudentHw.content[currentdocPreview].type === 'image'" :src="nowStudentHw.content[currentdocPreview].url" style="border-radius: 5px;max-height: 700px !important;max-width: 100% !important;" />
                                         <audio v-if="nowStudentHw.content[currentdocPreview].type === 'audio'" controls>
                                             <source :src="nowStudentHw.content[currentdocPreview].url" />
@@ -256,10 +256,11 @@ export default {
             let code = this.homeWork.scope == "private" ? this.homeWork.creatorId : this.homeWork.school
             // 授权
             let sas = await this.$tools.getBlobSas(code)
+            let sasString = "?" + sas.sas
             
             if(this.nowStudentHw.content.length) {
                 this.nowStudentHw.content.map(con => {
-                    con.url = con.url + sas
+                    con.url = con.url + sasString
                 })
             }
         },
@@ -303,6 +304,7 @@ export default {
             this.star = 0
             this.comment = ""
             this.getAllComment()
+            this.currentdocPreview = 0
         },
 
         // 点评
@@ -343,6 +345,7 @@ export default {
             this.activeIndex -= 1
             this.students[this.activeIndex]._highlight = true
             this.getAllComment()
+            this.currentdocPreview = 0
         },
         // 下一位
         nextMate() {
@@ -351,6 +354,7 @@ export default {
             this.activeIndex += 1
             this.students[this.activeIndex]._highlight = true
             this.getAllComment()
+            this.currentdocPreview = 0
         },
         // 切换作业
         changeDocNo(docNo) {

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

@@ -320,7 +320,7 @@ export default {
             let code = info.scope == "private" ? info.creatorId : info.school
             let sas = await this.$tools.getBlobSas(code)
             info.attachments.map(item => {
-                item.url = item.url + sas
+                item.url = item.url + "?" + sas.sas
             })
         },
         // 文件展示
@@ -345,10 +345,11 @@ export default {
         uploadHome() {
             return new Promise(async(r, j) => {
                 this.isUpload = true
-                let blobHost = this.$tools.getBlobHost()
+                // let blobHost = this.$tools.getBlobHost()
                 let code = this.homeworkInfo.scope == "private" ? this.homeworkInfo.creatorId : this.homeworkInfo.school
                 // 可以写的授权码
                 let sas = await this.$api.blob.blobSasRCW({name: code, role: "student"})
+                let blobHost = sas.url
                 // 学生id
                 let cont = this.userInfo.sub
                 let homeworkId = this.homeworkInfo.id
@@ -473,7 +474,7 @@ export default {
         async loadAttach(file) {
             let code = this.homeworkInfo.scope == "private" ? this.homeworkInfo.creatorId : this.homeworkInfo.school
             let sas = await this.$tools.getBlobSas(code)
-            let curFile = file.url + sas
+            let curFile = file.url + "?" + sas.sas
             const downloadRes = async () => {
                 let response = await fetch(curFile); // 内容转变成blob地址
                 let blob = await response.blob();  // 创建隐藏的可下载链接

+ 7 - 5
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue

@@ -594,7 +594,7 @@
                         code: codes.scope === 'school' ? codes.school : codes.creatorId,
                         blob: data
                     }
-                    let blob = this.formUrl(code)
+                    let blob = await this.formUrl(code)
                     code.blob = blob
                     datas = await this.$evTools.getComposeItem(code)
                     return datas
@@ -611,24 +611,26 @@
                     let blobUrl = JSON.parse(decodeURIComponent(profile, "utf-8")).blob_uri
                     let host = blobUrl.substring(0, blobUrl.lastIndexOf('/')) */
 
-                    let blobHost = this.$tools.getBlobHost()
+                    // let blobHost = this.$tools.getBlobHost()
                     // 获取授权码('?授权码')
                     let sas = await this.$tools.getBlobSas(code)
-                    urlImg = `${blobHost}/${code}/${item}${sas}`
+                    let blobHost = sas.url
+                    urlImg = `${blobHost}/${code}/${item}?${sas.sas}`
                     return urlImg
                 } else {
                     return ""
                 }
             },
             // 处理学生作答数据blob地址
-            formUrl(data) {
+            async formUrl(data) {
                 // data.blob 现在是相对路径(xxxxx.json)
                 let a = ""
                 /* let profile = localStorage.student_profile || localStorage.user_profile
                 let blobUrl = JSON.parse(decodeURIComponent(profile, "utf-8")).blob_uri
                 let host = blobUrl.substring(0, blobUrl.lastIndexOf("/")) */
                 
-				let blobHost = this.$tools.getBlobHost()
+                let sas = await this.$tools.getBlobSas(data.code)
+				let blobHost = sas.url
                 /* 例子:
                     https://teammodelstorage.blob.core.chinacloudapi.cn / {data.code: hbcn 或 1595321354} /exam/ {data.blob: xxxxx.json}
                 */

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

@@ -670,7 +670,7 @@
                     let req = {
                         id: this.getItemTitle.id,
                         answer: this.checkers,
-                        studentId: this.getUserInfo.studentId,
+                        studentId: this.getStuUserInfo.studentId,
                         classIds: this.getItemTitle.classIds,
                         subjectId: this.getExamInfo.subject.id,
                         multipleRule: this.getExamInfo.multipleRule, //阅卷规则
@@ -911,7 +911,7 @@
                 "getPaperInfo",
                 "getCurrentSubject",
                 "getExamInfo",
-                "getUserInfo"
+                "getStuUserInfo"
             ]),
             completeRate() {
                 if (this.examInfo.length) {

+ 4 - 2
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/QuesNaire.vue

@@ -318,9 +318,11 @@
 			// 获取blob里的问卷内容
 			getBlobItems(qnItem) {
 				return new Promise(async (resolve, reject) => {
-					let blobHost = this.$tools.getBlobHost()
+					// let blobHost = this.$tools.getBlobHost()
 					let cntr = qnItem.scope === 'school' ? qnItem.school : qnItem.code.replace('Survey-','')
-					let sasString = await this.$tools.getBlobSas(cntr)
+					let sas = await this.$tools.getBlobSas(cntr)
+					let sasString = "?" + sas.sas
+					let blobHost = sas.url
 					let fullIndexJsonPath = blobHost + '/' + cntr + qnItem.blob + sasString
 					// 根据试卷的Blob地址 去读取JSON文件
 					let promiseArr = []

+ 4 - 2
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/Vote.vue

@@ -332,11 +332,13 @@
             getBlobItems(qnItem) {
                 return new Promise(async (resolve, reject) => {
                     // blobHost例子:https://teammodelstorage.blob.core.chinacloudapi.cn/
-                    let blobHost = this.$tools.getBlobHost()
+                    // let blobHost = this.$tools.getBlobHost()
                     let code = qnItem.scope === 'private' ? qnItem.creatorId : qnItem.school
                     // 授权
                     let sas = await this.$tools.getBlobSas(code)
-                    let itemFullPath = blobHost + '/' + code + qnItem.recordUrl + sas
+                    let blobHost = sas.url
+                    let sasString = "?" + sas.sas
+                    let itemFullPath = blobHost + '/' + code + qnItem.recordUrl + sasString
                     // 根据试卷的Blob地址 去读取JSON文件
                     let promiseArr = []
                     promiseArr.push(new Promise(async (r, j) => {

+ 9 - 5
TEAMModelOS/ClientApp/src/utils/evTools.js

@@ -12,7 +12,7 @@ import { app } from '@/boot-app.js'
 export default {
 	/* 根据登录后的用户信息获取blobHOST域名 */
 	getBlobHost(){
-		let s = store.state.user.userProfile.blob_uri || store.state.user.studentProfile.blob_uri || 'https://teammodelstorage.blob.core.chinacloudapi.cn/hbcn'
+		let s = 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]
 	},
@@ -35,6 +35,7 @@ export default {
 			})
 		},
 	/* 获取试题保存在Blob的JSON文件 */
+	/* 创建Blob试题格式 */
 	createBlobItem(item){
 		return new Promise((r,j) => {
 			let itemJson = {
@@ -536,10 +537,12 @@ export default {
 		let curScope = examScope || paper.scope
 		console.log(...arguments);
 		return new Promise(async (r, j) => {
-			let blobHost = this.getBlobHost()
+			// let blobHost = this.getBlobHost()
 			// 根据试卷的Blob地址 去读取JSON文件
 			let cntr = paper.code
-			let sasString = await $tools.getBlobSas(cntr)
+			let sas = await $tools.getBlobSas(cntr)
+			let sasString = "?" + sas.sas
+			let blobHost = sas.url
 			let paperBlobPath = blobHost + '/' + cntr + paper.blob
 			let fullPath = paperBlobPath + '/index.json' + sasString
 			console.log(fullPath);
@@ -599,8 +602,9 @@ export default {
 			console.log(paper);
 			// 根据试卷的Blob地址 去读取JSON文件
 			let cntr = paper.code
-			let sasString = await $tools.getBlobSas(cntr)
-			let fullPath = paper.blob + sasString
+			let sas = await $tools.getBlobSas(cntr)
+			let sasString = sas.sas
+			let fullPath = paper.blob + "?" + sasString
 			try {
 				let jsonInfo = await $tools.getFile(fullPath)
 				let jsonData = JSON.parse(jsonInfo)

+ 3 - 2
TEAMModelOS/ClientApp/src/utils/public.js

@@ -420,8 +420,9 @@ export default {
 	},
 
 	/* 根据登录后的用户信息获取blobHOST域名 */
+	// 现在废弃,改用 getBlobSas() 返回的url
 	getBlobHost(){
-		let s = store.state.user.userProfile.blob_uri || store.state.user.studentProfile.blob_uri || 'https://teammodelstorage.blob.core.chinacloudapi.cn/hbcn'
+		let s = 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]
 	},
@@ -522,7 +523,7 @@ export default {
 				role: 'teacher'
 			}).then(res => {
 				if (!res.error) {
-					r('?' + res.sas)
+					r(res)
 				}
 			})
 		})

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

@@ -153,6 +153,7 @@
 			if(from.name !== 'answerSheet'){
 				to.meta.isKeep = false
 			}else{
+				// console.error('进入题库收到的',to.meta.isKeep)
 				to.meta.isKeep = true
 			}
 			next();

+ 4 - 2
TEAMModelOS/ClientApp/src/view/jyzx/Question.vue

@@ -194,9 +194,11 @@ export default {
         // 获取blob里的问卷内容
         getBlobItems(qnItem) {
             return new Promise(async (resolve, reject) => {
-                let blobHost = this.$tools.getBlobHost()
+                // let blobHost = this.$tools.getBlobHost()
                 let cntr = qnItem.scope === 'school' ? qnItem.school : qnItem.code.replace('Survey-','')
-                let sasString = await this.$tools.getBlobSas(cntr)
+                let sas = await this.$tools.getBlobSas(cntr)
+                let blobHost = sas.url
+                let sasString = "?" + sas.sas
                 let fullIndexJsonPath = blobHost + '/' + cntr + qnItem.blob + sasString
                 // 根据试卷的Blob地址 去读取JSON文件
                 let promiseArr = []

+ 5 - 3
TEAMModelOS/ClientApp/src/view/jyzx/Vote.vue

@@ -351,11 +351,13 @@ export default {
         getBlobItems(qnItem) {
             return new Promise(async (resolve, reject) => {
                 // blobHost例子:https://teammodelstorage.blob.core.chinacloudapi.cn/
-                let blobHost = this.$tools.getBlobHost()
+                // let blobHost = this.$tools.getBlobHost()
                 let code = qnItem.scope === 'private' ? qnItem.creatorId : qnItem.school
                 // 授权
-                let sas = await this.$tools.getBlobSas(code)
-                let itemFullPath = blobHost + '/' + code + qnItem.recordUrl + sas
+                let sas = await this.$tools.getBlobSas(cntr)
+                let blobHost = sas.url
+                let sasString = "?" + sas.sas
+                let itemFullPath = blobHost + '/' + code + qnItem.recordUrl + sasString
                 // 根据试卷的Blob地址 去读取JSON文件
                 let promiseArr = []
                 promiseArr.push(new Promise(async (r, j) => {

+ 2 - 2
TEAMModelOS/ClientApp/src/view/newsheet/BaseEditor.vue

@@ -919,9 +919,9 @@
 		display: none;
 		position: absolute;
 		top: -32px;
-		left: -2px;
+		left: -1px;
 		width: 770px;
-		border: 2px solid #000 !important;
+		border: 1px solid #000 !important;
 		border-bottom: 1px solid #dddddd !important;
 	}
 

+ 1 - 0
TEAMModelOS/ClientApp/src/view/newsheet/index.vue

@@ -589,6 +589,7 @@
 			if (to.name === 'schoolBank' || to.name ===
 				'personalBank') {
 				// 设置下一个路由的 meta
+				// console.error('此时题库的isKeep', to.meta.isKeep)
 				to.meta.isKeep = true; // 让 A 缓存,即不刷新
 			}
 			next();

+ 80 - 0
TEAMModelOS/Controllers/Third/Helpers/AESHelper.cs

@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TEAMModelOS.Controllers
+{
+    public class AESHelper
+    {
+
+        /// <summary>
+        /// 有密码的加密 
+        /// </summary>
+        /// <param name="toEncrypt">加密字符</param>
+        /// <param name="key">加密的密码</param>
+        /// <returns></returns>
+        public static string AESEncrypt(string toEncrypt, string key)
+        {
+            byte[] keyArray = hexStringTobyte(key);
+            byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
+            RijndaelManaged rDel = new RijndaelManaged();
+            rDel.KeySize = 128;
+            rDel.BlockSize = 128;
+            rDel.Key = keyArray;
+            rDel.Mode = CipherMode.ECB;
+            rDel.Padding = PaddingMode.PKCS7;
+            ICryptoTransform cTransform = rDel.CreateEncryptor();
+            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
+            return byteToHexString(resultArray);
+        }
+
+        /// <summary>
+        /// 解密
+        /// </summary>
+        /// <param name="toDecrypt">解密字符</param>
+        /// <param name="key">加密的密码</param>
+        /// <returns></returns>
+        public static string AESDecrypt(string toDecrypt, string key)
+        {
+            byte[] keyArray = hexStringTobyte(key);
+            byte[] dest = hexStringTobyte(toDecrypt);
+            RijndaelManaged rDel = new RijndaelManaged();
+            rDel.KeySize = 128;
+            rDel.BlockSize = 128;
+            rDel.Key = keyArray;
+            rDel.Mode = CipherMode.ECB;
+            rDel.Padding = PaddingMode.PKCS7;
+            ICryptoTransform cTransform = rDel.CreateDecryptor();
+            byte[] resultArray = cTransform.TransformFinalBlock(dest, 0, dest.Length);
+            return UTF8Encoding.UTF8.GetString(resultArray);
+        }
+
+
+        private static byte[] hexStringTobyte(String s)
+        {
+            if (string.IsNullOrEmpty(s)) return null;
+            s = s.ToLower();
+            int byteArrayLength = s.Length / 2;
+            byte[] b = new byte[byteArrayLength];
+            for (int i = 0; i < byteArrayLength; i++)
+            {
+                byte b0 = Convert.ToByte(s.Substring(i * 2, 2), 16);
+                b[i] = b0;
+            }
+            return b;
+        }
+
+        public static string byteToHexString(byte[] t)
+        {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < t.Length; i++)
+            {
+                sb.Append(t[i].ToString("x").PadLeft(2, '0'));
+            }
+            return sb.ToString().ToUpper();
+        }
+    }
+}

+ 413 - 1
TEAMModelOS/Controllers/Third/ScController.cs

@@ -49,10 +49,27 @@ namespace TEAMModelOS.Controllers.Third
         private readonly AzureServiceBusFactory _serviceBus;
         private readonly AzureRedisFactory _azureRedis;
         private readonly CoreAPIHttpService _accountHttpService;
+        private readonly ScsApisService _scsApisService;
         public readonly string type = "scsyxpt";
+        /// <summary>
+        /// 机构安全码
+        /// </summary>
+        public string _sc_passKey;
+        /// <summary>
+        /// 机构ID
+        /// </summary>
+        public string _sc_trainComID;
+        /// <summary>
+        /// 机构 AES 密钥
+        /// </summary>
+        public string _sc_privateKey;
+        /// <summary>
+        /// 访问地址
+        /// </summary>
+        public   string _sc_url;
         public IConfiguration _configuration { get; set; }
         public ScController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage,
-          AzureRedisFactory azureRedis, AzureServiceBusFactory serviceBus, IConfiguration configuration, CoreAPIHttpService accountHttpService)
+          AzureRedisFactory azureRedis, AzureServiceBusFactory serviceBus, IConfiguration configuration, CoreAPIHttpService accountHttpService, ScsApisService scsApisService)
         {
             _azureCosmos = azureCosmos;
             _snowflakeId = snowflakeId;
@@ -63,8 +80,403 @@ namespace TEAMModelOS.Controllers.Third
             _configuration = configuration;
             _azureRedis = azureRedis;
             _accountHttpService = accountHttpService;
+            _scsApisService = scsApisService;
+            _sc_passKey = _configuration.GetValue<string>("Third:scsyxpt:passKey");
+            _sc_trainComID = _configuration.GetValue<string>("Third:scsyxpt:trainComID");
+            _sc_privateKey = _configuration.GetValue<string>("Third:scsyxpt:privateKey");
+            _sc_url = _configuration.GetValue<string>("Third:scsyxpt:url");
+        }
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="json"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("get-list")]
+        [AllowAnonymous]
+        public async Task<IActionResult> GetProjectList(JsonElement json) {
+            // 5.3.1.1获取项目列表
+            string trainComID = _sc_trainComID;
+            string Code = "GetProjectInfoByTrainComID";
+            Dictionary<string, object> parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", _sc_trainComID);
+            ScsResult GetProjectInfoByTrainComID = await _scsApisService.Post(_sc_url, Code, _sc_passKey,_sc_privateKey, parameterMap);
+
+            // 5.3.1.2获取学员名单
+            Code = "GetTeachersListByProject";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            parameterMap.Add("ProjectID", "22");
+            parameterMap.Add("ProjectItemID", "23");
+            ScsResult GetTeachersListByProject = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+            // 5.3.1.3通过项目编号获取学员测评能力项
+            Code = "GetDiagnosisListByProject";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            parameterMap.Add("ProjectID", "22");
+            parameterMap.Add("ProjectItemID", "22");
+            parameterMap.Add("PXID", "28496");
+            ScsResult GetDiagnosisListByProject = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+            // 补充
+            // 5.3.1.20获取学校设置的可选能力点
+            Code = "GetDiagnosisListByProject_V2";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            //parameterMap.Add("ProjectID", "22");
+            //parameterMap.Add("ProjectItemID", "22");
+            parameterMap.Add("PXID", "28496");
+            ScsResult GetDiagnosisListByProject_V2 = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+
+
+            // 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);
+
+            // 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);
+
+            // 5.3.1.6获取能力测评体系字典值数据
+            Code = "GetDiagnosisDic";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            ScsResult GetDiagnosisDic = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+            // 5.3.1.7获取能力测评评价类型字典值数据
+            Code = "GetDiagnosisItemDic";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            parameterMap.Add("DiagnosisDicID", "3");
+            ScsResult GetDiagnosisItemDic = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+            // 5.3.1.8获取能力测评评价类型细则字典值数据
+            Code = "GetchoiceDic";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            parameterMap.Add("DiagnosisItemID", "4");
+            ScsResult GetchoiceDic = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+            // 5.3.1.9根据培训ID与机构ID获取老师信息
+            Code = "GetTeacherInfoByPXID";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            parameterMap.Add("PXID", "55024");
+            ScsResult GetTeacherInfoByPXID = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+            // 5.3.1.10根据培训项目ID与学校ID获取学校方案
+            Code = "GetSchoolPlanBySchoolID";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            parameterMap.Add("ProjectItemID", "3");
+            parameterMap.Add("SchoolID", "220913");
+            parameterMap.Add("Type", "0");
+            ScsResult GetSchoolPlanBySchoolID = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+            // 5.3.1.11获取跳转学员信息
+            Code = "GetSingleTeacherByProject";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            parameterMap.Add("Pxid", "55024");
+            parameterMap.Add("Tid", "38616");
+            ScsResult GetSingleTeacherByProject = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+            // 5.3.1.12学员培训基本情况批量回写
+            Code = "UpdateTeacherListSituation";
+            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);
+            }
+            ScsResult UpdateTeacherListSituation = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
+
+
+            // 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);
+            }
+
+            {
+                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);
+            }
+            ScsResult UpdateTeacherListDiagnosis = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
+
+
+            // 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);
+
+
+            // 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);
+            }
+            ScsResult UploadSBTARPDFList = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
+
+
+            // 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);
+
+            //  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);
+            }
+            ScsResult UploadKTSLList = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterContent);
+
+
+            // 5.3.1.18根据机构ID、项目ID、子项目ID返回学校列表
+            Code = "GetSchoolList";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            parameterMap.Add("ProjectID", "22");
+            parameterMap.Add("ProjectItemID", "21");
+            ScsResult GetSchoolList = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+            // 5.3.1.19获取项目设置的可选能力点
+            Code = "GetProjectDiagnosis";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            parameterMap.Add("ProjectID", "22");
+            parameterMap.Add("ProjectItemID", "21");
+            ScsResult GetProjectDiagnosis = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+            // 5.3.1.20获取学校设置的可选能力点
+            Code = "GetSchoolDiagnosis";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", trainComID);
+            parameterMap.Add("ProjectID", "22");
+            parameterMap.Add("SchoolID", "200001");
+            ScsResult GetSchoolDiagnosis = await _scsApisService.Post(_sc_url, Code, _sc_passKey, _sc_privateKey, parameterMap);
+
+            return Ok(new
+            {
+                GetProjectInfoByTrainComID,
+                GetTeachersListByProject,
+                GetDiagnosisListByProject,
+                GetDiagnosisListByProject_V2,
+                UpdateTeacherSituation,
+                UpdateTeacherDiagnosis,
+                GetDiagnosisDic,
+                GetDiagnosisItemDic,
+                GetchoiceDic,
+                GetTeacherInfoByPXID,
+                GetSchoolPlanBySchoolID,
+                GetSingleTeacherByProject,
+                UpdateTeacherListSituation,
+                UpdateTeacherListDiagnosis,
+                UploadSBTARPDF,
+                UploadSBTARPDFList,
+                UploadKTSL,
+                UploadKTSLList,
+                GetSchoolList,
+                GetProjectDiagnosis,
+                GetSchoolDiagnosis
+            });
         }
 
+        public class ScsResult {
+            public bool result { get; set; }
+            public string reason { get; set; }
+            public string content { get; set; }
+        }
         /// <summary>
         /// 
         /// </summary>

+ 59 - 0
TEAMModelOS/Controllers/Third/ScsApisService.cs

@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Net.Http.Json;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.Extension;
+using static TEAMModelOS.Controllers.Third.ScController;
+
+namespace TEAMModelOS.Controllers
+{
+    public class ScsApisService
+    {
+       
+        private readonly HttpClient _httpClient;
+        public ScsApisService(HttpClient httpClient)
+        {
+            _httpClient = httpClient;
+        }
+        public async   Task<ScsResult> Post(string url, string Code, string PassKey,string privateKey, Dictionary<string ,object> data)
+        {
+           
+            string Content = AESHelper.AESEncrypt(data.ToJsonString(), privateKey);
+            string paramStr = "Code={0}&PassKey={1}&Content={2}";
+            string sendMsg = string.Format(paramStr, Code, PassKey, Content);
+            #region 签名 Signature
+            SortedDictionary<string, string> signatureDC = new SortedDictionary<string, string>();
+            var timeSpan = (DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0));
+            signatureDC["t"] = timeSpan.TotalMilliseconds.ToString();
+            signatureDC["Code"] = Code;
+            signatureDC["PassKey"] = PassKey;
+            string signatureStr = signatureDC.ToJsonString();
+            string signature = AESHelper.AESEncrypt(signatureStr, privateKey);
+            #endregion
+            string result = "";
+            _httpClient.DefaultRequestHeaders.Add("Signature",signature);
+            using (var request = new HttpRequestMessage())
+            {
+                request.Method = new HttpMethod("POST");
+                request.RequestUri = new Uri(url);
+                request.Content = new StringContent(sendMsg);
+                request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
+                var response = await _httpClient.SendAsync(request);
+                result = await response.Content.ReadAsStringAsync();
+            }
+            ScsResult scsResult = result.ToObject<ScsResult>();
+            if (scsResult.result)
+            {
+                scsResult.content = AESHelper.AESDecrypt(scsResult.content, privateKey);
+                
+            }
+            return scsResult;
+            
+        }
+    }
+}

+ 0 - 193
TEAMModelOS/Controllers/Third/SsoController.cs

@@ -1,193 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using TEAMModelOS.Models;
-using TEAMModelOS.SDK.DI;
-using System.Text.Json;
-using TEAMModelOS.SDK.Models;
-using Microsoft.AspNetCore.Http;
-using TEAMModelOS.SDK.Extension;
-using Azure.Cosmos;
-using System.Text;
-using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
-using Microsoft.Extensions.Options;
-using Azure.Messaging.ServiceBus;
-using Microsoft.Extensions.Configuration;
-using TEAMModelOS.Services.Common;
-using HTEXLib.COMM.Helpers;
-using TEAMModelOS.SDK;
-using System.IdentityModel.Tokens.Jwt;
-using TEAMModelOS.Services;
-using TEAMModelOS.SDK.Models.Service;
-using System.IO;
-using System.Dynamic;
-
-namespace TEAMModelOS.Controllers
-{
-    /// <summary>
-    /// 
-    /// </summary>
-    ///  
-    [ProducesResponseType(StatusCodes.Status200OK)]
-    [ProducesResponseType(StatusCodes.Status400BadRequest)]
-    //[Authorize(Roles = "IES5")]
-    [Route("sso")]
-    //[Route("api/[controller]")]
-    [ApiController]
-    public class SsoController : ControllerBase
-    {
-        private readonly SnowflakeId _snowflakeId;
-        private readonly AzureCosmosFactory _azureCosmos;
-        private readonly DingDing _dingDing;
-        private readonly Option _option;
-        private readonly AzureStorageFactory _azureStorage;
-        private readonly AzureServiceBusFactory _serviceBus;
-        private readonly AzureRedisFactory _azureRedis;
-        private readonly CoreAPIHttpService _accountHttpService;
-        public IConfiguration _configuration { get; set; }
-        public SsoController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage,
-          AzureRedisFactory azureRedis, AzureServiceBusFactory serviceBus, IConfiguration configuration, CoreAPIHttpService accountHttpService)
-        {
-            _azureCosmos = azureCosmos;
-            _snowflakeId = snowflakeId;
-            _dingDing = dingDing;
-            _option = option?.Value;
-            _azureStorage = azureStorage;
-            _serviceBus = serviceBus;
-            _configuration = configuration;
-            _azureRedis = azureRedis;
-            _accountHttpService = accountHttpService;
-        }
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        [HttpPost("opt-tmdid-bind")]
-        public async Task<IActionResult> OptTmdidTid(JsonElement request) {
-            string type = "";
-            try {
-                if (!request.TryGetProperty("opt", out JsonElement _opt))
-                {
-                    return BadRequest();
-                }
-                //四川研训平台跳转隐式登录/或者绑定IES平台接入规范
-                if (request.TryGetProperty("Pxid", out JsonElement _Pxid) &&
-                            request.TryGetProperty("Webid", out JsonElement _Webid) &&
-                            request.TryGetProperty("tid", out JsonElement _tid) &&
-                            request.TryGetProperty("time", out JsonElement _time) &&
-                            request.TryGetProperty("Encrypt", out JsonElement _Encrypt))
-                {
-                    string parmas = $"Pxid={_Pxid}&Webid={_Webid}&tid={_tid}&time={_time}";
-                    if (Md5Hash.GetMd5String(parmas).Equals($"{_Encrypt}"))
-                    {
-                        //四川研训平台跳转隐式登录/或者绑定IES平台接入规范
-                        type = "scsyxpt";
-                        long ssotime = long.Parse($"{_time}");
-                        long nowtime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
-                        if (nowtime - ssotime > 60 * 10)//10分钟有效期
-                        { 
-                          //  return Ok(new { status = 2, msg = "登录超时!" });
-                        }
-                    }
-                    else
-                    {
-                        return Ok(new { status = 1, msg = "参数异常!" });
-                    }
-                }
-                ///其他平台跳转隐式登录/或者绑定IES平台接入规范
-                else
-                {
-                    return Ok(new { status = 1, msg = "参数异常!" });
-                }
-                Teacher teacher = null;
-                switch (true) {
-                    case bool when $"{_opt}".Equals("CheckBindInfo", StringComparison.OrdinalIgnoreCase):
-                        if (type.Equals("scsyxpt")) {
-                            //四川研训平台跳转隐式登录/或者绑定IES平台接入规范
-                            string sql = $"SELECT distinct value(c) FROM c join A1 in  c.binds where A1.pxid='{_Pxid}' and A1.webid='{_Webid}' and A1.tid='{_tid}'";
-                            await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sql,
-                                requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
-                            {
-                                teacher = item;
-                                break;
-                            }
-                        }
-                        if (teacher == null)
-                        {
-                            return Ok(new { status = 0, msg = "没有绑定!" });
-                        }
-                        else
-                        {
-                            var url = _configuration.GetValue<string>("HaBookAuth:CoreAPI");
-                            var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
-                            var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
-                            var location = _option.Location;
-                            (int code, string content) = await _accountHttpService.Implicit(clientID, clientSecret, location,$"{url}/oauth2/implicit",
-                                new Dictionary<string, string>()
-                                {
-                                    { "grant_type", "implicit" },
-                                    { "client_id",clientID },
-                                    { "account",teacher.id },
-                                    { "nonce",Guid.NewGuid().ToString()}
-                                });
-                            dynamic implicit_token = new ExpandoObject();
-                            if (!string.IsNullOrEmpty(content)) {
-                                implicit_token = content.ToObject<JsonElement>();
-                            }
-                            return Ok(new
-                            {
-                                location = _option.Location,
-                                status = 200,
-                                implicit_token
-                            });
-                        }
-                    case bool when $"{_opt}".Equals("BindTmdidInfo", StringComparison.OrdinalIgnoreCase):
-                        if (!request.TryGetProperty("id_token", out JsonElement id_token)) return BadRequest();
-                        var jwt = new JwtSecurityToken(id_token.GetString());
-                        if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
-                        var id = jwt.Payload.Sub;
-                        jwt.Payload.TryGetValue("name", out object name);
-                        jwt.Payload.TryGetValue("picture", out object picture);
-                        var client = _azureCosmos.GetCosmosClient();
-                        if ( teacher == null)
-                        {
-                            teacher = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Teacher>(id, new PartitionKey("Base"));
-                        }
-                        if (type.Equals("scsyxpt")) {
-                            //先检查绑定的平台是否已经被绑定
-                            //四川研训平台跳转隐式登录/或者绑定IES平台接入规范
-                            string sql = $"SELECT distinct value(c) FROM c join A1 in  c.binds where A1.pxid='{_Pxid}' and A1.webid='{_Webid}' and A1.tid='{_tid}'";
-                            await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sql,
-                                requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
-                            {
-                                teacher = item;
-                                break;
-                            }
-
-                            //四川研训平台跳转隐式登录/或者绑定IES平台接入规范
-                            var bind = teacher.binds.FindAll(x => x.pxid.Equals($"{_Pxid}") && x.source.Equals($"{_Webid}") && x.userid.Equals($"{_tid}"));
-                            if (bind.IsEmpty())
-                            {
-                                teacher.binds.Add(new Teacher.ThirdBind { pxid =new HashSet<string> { $"{_Pxid}" }, userid = $"{_tid}", source = $"{_Webid}" , type = type });
-                            }
-                        }
-                        await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>( teacher, id, new PartitionKey("Base"));
-                        return Ok(new
-                        {
-                            location = _option.Location,
-                            status = 200,
-                        });
-                }
-            } catch (Exception ex)
-            {
-                await _dingDing.SendBotMsg($"IES5,{_option.Location},third/sctrain/opt-tmdid-tid()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
-                return Ok(new { status = 1, msg = "参数异常!" });
-            }
-            return Ok(new { status = 1, msg = "参数异常!" });
-        }
-    }
-}

+ 2 - 0
TEAMModelOS/Startup.cs

@@ -23,6 +23,7 @@ using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Primitives;
 using Microsoft.IdentityModel.Tokens;
+using TEAMModelOS.Controllers;
 using TEAMModelOS.Filter;
 using TEAMModelOS.Models;
 using TEAMModelOS.SDK;
@@ -107,6 +108,7 @@ namespace TEAMModelOS
             services.AddHttpClient<DingDing>();
             services.AddHttpClient<NotificationService>();
             services.AddHttpClient<CoreAPIHttpService>();
+            services.AddHttpClient<ScsApisService>();
             services.AddMemoryCache();
             services.AddSpaStaticFiles(opt => opt.RootPath = "ClientApp/dist");
             services.AddControllers().AddJsonOptions(options => { options.JsonSerializerOptions.IgnoreNullValues = false; });

+ 9 - 0
TEAMModelOS/appsettings.Development.json

@@ -54,5 +54,14 @@
       "getnotification": "https://api2.teammodel.net/service/getnotification",
       "delnotification": "https://api2.teammodel.net/service/delnotification"
     }
+  },
+  "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" 
+    }
   }
 }