jingshitijiao 接口
This commit is contained in:
parent
feca273bcc
commit
42ebe0b3d2
64
WeChatApplet/Controllers/JingShiTiJiaoController.cs
Normal file
64
WeChatApplet/Controllers/JingShiTiJiaoController.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using YD_WeChatApplet.Api.Services.Interface;
|
||||
using YD_WeChatApplet.Commons.Dto.HomeWork;
|
||||
using YD_WeChatApplet.Commons.Dto.JingShiTiJiao;
|
||||
using YD_WeChatApplet.Services;
|
||||
|
||||
namespace YD_WeChatApplet.Api.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// 京师体教
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[ApiExplorerSettings(GroupName = "v1")]
|
||||
[Route("[controller]")]
|
||||
[AllowAnonymous]
|
||||
public class JingShiTiJiaoController : ControllerBase
|
||||
{
|
||||
private readonly IJingShiTiJiaoService _jingShiTiJiaoService;
|
||||
|
||||
/// <summary>
|
||||
/// 京师体教
|
||||
/// </summary>
|
||||
/// <param name="jingShiTiJiaoService"></param>
|
||||
public JingShiTiJiaoController(IJingShiTiJiaoService jingShiTiJiaoService)
|
||||
{
|
||||
_jingShiTiJiaoService = jingShiTiJiaoService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据教师获取教师年级班级信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("GetClassListByTeacher")]
|
||||
public async Task<TeacherClassData> GetClassListByTeacher(string teacherNo)
|
||||
{
|
||||
var res = await _jingShiTiJiaoService.GetClassListByTeacher(teacherNo);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据班级编号获取学生列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("GetStuListByClass")]
|
||||
public async Task<List<StudentDto>> GetStuListByClass(string classNo)
|
||||
{
|
||||
var res = await _jingShiTiJiaoService.GetStuListByClass(classNo);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据学生编号获取学生详情
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("GetStudentInfo")]
|
||||
public async Task<StudentDetailDto> GetStudentInfo(string stuNo)
|
||||
{
|
||||
var res = await _jingShiTiJiaoService.GetStudentInfo(stuNo);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
140
WeChatApplet/Services/Impl/JingShiTiJiaoService.cs
Normal file
140
WeChatApplet/Services/Impl/JingShiTiJiaoService.cs
Normal file
@ -0,0 +1,140 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Channels;
|
||||
using YD_WeChatApplet.Api.Services.Interface;
|
||||
using YD_WeChatApplet.Api.Utilities;
|
||||
using YD_WeChatApplet.Commons.Dto.JingShiTiJiao;
|
||||
using YD_WeChatApplet.Commons.Utils;
|
||||
|
||||
namespace YD_WeChatApplet.Api.Services.Impl
|
||||
{
|
||||
/// <summary>
|
||||
/// 京师体教接口服务
|
||||
/// </summary>
|
||||
public class JingShiTiJiaoService : IJingShiTiJiaoService
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据教师获取教师年级班级信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<TeacherClassData> GetClassListByTeacher(string teacherNo)
|
||||
{
|
||||
var res = new TeacherClassData();
|
||||
|
||||
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
string nonce = SaTokenSignHelper.RandomString(20);
|
||||
|
||||
// 1. 签名参数
|
||||
var paramMap = new Dictionary<string, object>
|
||||
{
|
||||
{ "channel", AppSettings.JingShiTiJiao.Channel },
|
||||
{ "teacherNo", teacherNo },
|
||||
{ "timestamp", timestamp },
|
||||
{ "nonce", nonce }
|
||||
};
|
||||
|
||||
// 4. 构建签名 QueryString
|
||||
string queryStr = SaTokenSignHelper.BuildQueryString(paramMap, AppSettings.JingShiTiJiao.SecretKey);
|
||||
|
||||
// 5. 拼接最终 URL
|
||||
string url = $"{AppSettings.JingShiTiJiao.BaseUrl}/api/open/class/by/teacher?{queryStr}";
|
||||
|
||||
string json = await HttpManager.HttpGetAsync(url);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
return res;
|
||||
|
||||
var data = JsonConvert.DeserializeObject<JingShiResponse<TeacherClassData>>(json);
|
||||
if (data != null && data.Code == 0)
|
||||
{
|
||||
return data.Data;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据班级编号获取学生列表
|
||||
/// </summary>
|
||||
/// <param name="classNo"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public async Task<List<StudentDto>> GetStuListByClass(string classNo)
|
||||
{
|
||||
var res = new List<StudentDto>();
|
||||
|
||||
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
string nonce = SaTokenSignHelper.RandomString(20);
|
||||
|
||||
// 1. 签名参数
|
||||
var paramMap = new Dictionary<string, object>
|
||||
{
|
||||
{ "channel", AppSettings.JingShiTiJiao.Channel },
|
||||
{ "classNo", classNo },
|
||||
{ "timestamp", timestamp },
|
||||
{ "nonce", nonce }
|
||||
};
|
||||
|
||||
// 4. 构建签名 QueryString
|
||||
string queryStr = SaTokenSignHelper.BuildQueryString(paramMap, AppSettings.JingShiTiJiao.SecretKey);
|
||||
|
||||
// 5. 拼接最终 URL
|
||||
string url = $"{AppSettings.JingShiTiJiao.BaseUrl}/api/open/stu/by/class?{queryStr}";
|
||||
|
||||
string json = await HttpManager.HttpGetAsync(url);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
return res;
|
||||
|
||||
var data = JsonConvert.DeserializeObject<JingShiResponse<List<StudentDto>>>(json);
|
||||
if (data != null && data.Code == 0)
|
||||
{
|
||||
return data.Data;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据学生编号获取学生详情
|
||||
/// </summary>
|
||||
/// <param name="stuNo"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<StudentDetailDto> GetStudentInfo(string stuNo)
|
||||
{
|
||||
var res = new StudentDetailDto();
|
||||
|
||||
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
string nonce = SaTokenSignHelper.RandomString(20);
|
||||
|
||||
// 1. 签名参数
|
||||
var paramMap = new Dictionary<string, object>
|
||||
{
|
||||
{ "channel", AppSettings.JingShiTiJiao.Channel },
|
||||
{ "stuNo", stuNo },
|
||||
{ "timestamp", timestamp },
|
||||
{ "nonce", nonce }
|
||||
};
|
||||
|
||||
// 4. 构建签名 QueryString
|
||||
string queryStr = SaTokenSignHelper.BuildQueryString(paramMap, AppSettings.JingShiTiJiao.SecretKey);
|
||||
|
||||
// 5. 拼接最终 URL
|
||||
string url = $"{AppSettings.JingShiTiJiao.BaseUrl}/api/open//stu/info?{queryStr}";
|
||||
|
||||
string json = await HttpManager.HttpGetAsync(url);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
return res;
|
||||
|
||||
var data = JsonConvert.DeserializeObject<JingShiResponse<StudentDetailDto>>(json);
|
||||
if (data != null && data.Code == 0)
|
||||
{
|
||||
return data.Data;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
WeChatApplet/Services/Interface/IJingShiTiJiaoService.cs
Normal file
30
WeChatApplet/Services/Interface/IJingShiTiJiaoService.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using YD_WeChatApplet.Commons.Dto.JingShiTiJiao;
|
||||
|
||||
namespace YD_WeChatApplet.Api.Services.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// 京师体教接口
|
||||
/// </summary>
|
||||
public interface IJingShiTiJiaoService
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据教师获取教师年级班级信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<TeacherClassData> GetClassListByTeacher(string teacherNo);
|
||||
|
||||
/// <summary>
|
||||
/// 根据班级编号获取学生列表
|
||||
/// </summary>
|
||||
/// <param name="classNo"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<StudentDto>> GetStuListByClass(string classNo);
|
||||
|
||||
/// <summary>
|
||||
/// 根据学生编号获取学生详情
|
||||
/// </summary>
|
||||
/// <param name="stuNo"></param>
|
||||
/// <returns></returns>
|
||||
Task<StudentDetailDto> GetStudentInfo(string stuNo);
|
||||
}
|
||||
}
|
||||
@ -70,6 +70,8 @@ namespace YD_WeChatApplet
|
||||
services.AddScoped<IFrameworkService, FrameworkService>();
|
||||
|
||||
services.AddSingleton<ICacheService, RedisCacheService>();
|
||||
|
||||
services.AddSingleton<IJingShiTiJiaoService, JingShiTiJiaoService>();
|
||||
services.AddSession();
|
||||
services.AddMemoryCache();
|
||||
services.AddHttpContextAccessor();
|
||||
|
||||
@ -30,6 +30,11 @@
|
||||
/// </summary>
|
||||
public static YDWeChatAppletOSS YDWeChatAppletOSS { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// JingShiTiJiao
|
||||
/// </summary>
|
||||
public static JingShiTiJiao JingShiTiJiao { get; set; }
|
||||
|
||||
|
||||
public static string TokenHeaderName = "Authorization";
|
||||
|
||||
@ -47,6 +52,7 @@
|
||||
ALiYunOSS = configuration.GetSection("ALiYunOSS").Get<ALiYunOSS>();
|
||||
WeChatQA = configuration.GetSection("WeChatQA").Get<WeChatQA>();
|
||||
YDWeChatAppletOSS = configuration.GetSection("YDWeChatAppletOSS").Get<YDWeChatAppletOSS>();
|
||||
JingShiTiJiao = configuration.GetSection("JingShiTiJiao").Get<JingShiTiJiao>();
|
||||
}
|
||||
|
||||
public class LoggingConfig
|
||||
@ -103,4 +109,11 @@
|
||||
public string BucketName { get; set; }
|
||||
public string Prefix { get; set; }
|
||||
}
|
||||
|
||||
public class JingShiTiJiao
|
||||
{
|
||||
public string Channel { get; set; }
|
||||
public string SecretKey { get; set; }
|
||||
public string BaseUrl { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,5 +62,11 @@
|
||||
"YDWeChatAppletOSS": {
|
||||
"BucketName": "yuedong-wechatapplet",
|
||||
"Prefix": "Upload"
|
||||
},
|
||||
|
||||
"JingShiTiJiao": {
|
||||
"Channel": "sk-yuedong",
|
||||
"SecretKey": "JSTJ-kGfs6J7bkgdxr9mz",
|
||||
"BaseUrl": "https://api-test.aitibao.com"
|
||||
}
|
||||
}
|
||||
|
||||
66
YD_WeChatApplet.Commons/Dto/JingShiTiJiao/JingShiResponse.cs
Normal file
66
YD_WeChatApplet.Commons/Dto/JingShiTiJiao/JingShiResponse.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace YD_WeChatApplet.Commons.Dto.JingShiTiJiao
|
||||
{
|
||||
/// <summary>
|
||||
/// 京师接口统一返回结果泛型封装
|
||||
/// </summary>
|
||||
/// <typeparam name="T">data 对应的数据类型</typeparam>
|
||||
public class JingShiResponse<T>
|
||||
{
|
||||
[JsonProperty("code")]
|
||||
public int Code { get; set; }
|
||||
|
||||
[JsonProperty("msg")]
|
||||
public string Msg { get; set; }
|
||||
|
||||
[JsonProperty("data")]
|
||||
public T Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 判断接口是否成功
|
||||
/// </summary>
|
||||
public bool IsSuccess => Code == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 老师信息
|
||||
/// </summary>
|
||||
public class TeacherClassData
|
||||
{
|
||||
[JsonProperty("school")]
|
||||
public string School { get; set; }
|
||||
|
||||
[JsonProperty("teacherNo")]
|
||||
public string TeacherNo { get; set; }
|
||||
|
||||
[JsonProperty("teacherName")]
|
||||
public string TeacherName { get; set; }
|
||||
|
||||
[JsonProperty("classList")]
|
||||
public List<GradeDto> GradeList { get; set; }
|
||||
}
|
||||
|
||||
public class GradeDto
|
||||
{
|
||||
[JsonProperty("gradeNo")]
|
||||
public string GradeNo { get; set; }
|
||||
|
||||
[JsonProperty("gradeName")]
|
||||
public string GradeName { get; set; }
|
||||
|
||||
[JsonProperty("claArray")]
|
||||
public List<ClassDto> ClassList { get; set; }
|
||||
}
|
||||
|
||||
public class ClassDto
|
||||
{
|
||||
[JsonProperty("classNo")]
|
||||
public string ClassNo { get; set; }
|
||||
|
||||
[JsonProperty("className")]
|
||||
public string ClassName { get; set; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace YD_WeChatApplet.Commons.Dto.JingShiTiJiao
|
||||
{
|
||||
/// <summary>
|
||||
/// 学生详情 DTO
|
||||
/// </summary>
|
||||
public class StudentDetailDto
|
||||
{
|
||||
[JsonProperty("stuNo")]
|
||||
public string StuNo { get; set; }
|
||||
|
||||
[JsonProperty("stuName")]
|
||||
public string StuName { get; set; }
|
||||
|
||||
[JsonProperty("school")]
|
||||
public string School { get; set; }
|
||||
|
||||
[JsonProperty("teacherNo")]
|
||||
public string TeacherNo { get; set; }
|
||||
|
||||
[JsonProperty("teacherName")]
|
||||
public string TeacherName { get; set; }
|
||||
|
||||
[JsonProperty("gradeNo")]
|
||||
public string GradeNo { get; set; }
|
||||
|
||||
[JsonProperty("gradeName")]
|
||||
public string GradeName { get; set; }
|
||||
|
||||
[JsonProperty("classNo")]
|
||||
public string ClassNo { get; set; }
|
||||
|
||||
[JsonProperty("className")]
|
||||
public string ClassName { get; set; }
|
||||
|
||||
[JsonProperty("gender")]
|
||||
public string Gender { get; set; }
|
||||
|
||||
[JsonProperty("age")]
|
||||
public int Age { get; set; }
|
||||
}
|
||||
}
|
||||
51
YD_WeChatApplet.Commons/Dto/JingShiTiJiao/StudentDto.cs
Normal file
51
YD_WeChatApplet.Commons/Dto/JingShiTiJiao/StudentDto.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace YD_WeChatApplet.Commons.Dto.JingShiTiJiao
|
||||
{
|
||||
/// <summary>
|
||||
/// 学生信息 DTO
|
||||
/// </summary>
|
||||
public class StudentDto
|
||||
{
|
||||
[JsonProperty("stuNo")]
|
||||
public string StuNo { get; set; }
|
||||
|
||||
[JsonProperty("stuName")]
|
||||
public string StuName { get; set; }
|
||||
|
||||
[JsonProperty("school")]
|
||||
public string School { get; set; }
|
||||
|
||||
[JsonProperty("teacherNo")]
|
||||
public string TeacherNo { get; set; }
|
||||
|
||||
[JsonProperty("teacherName")]
|
||||
public string TeacherName { get; set; }
|
||||
|
||||
[JsonProperty("gradeNo")]
|
||||
public string GradeNo { get; set; }
|
||||
|
||||
[JsonProperty("gradeName")]
|
||||
public string GradeName { get; set; }
|
||||
|
||||
[JsonProperty("classNo")]
|
||||
public string ClassNo { get; set; }
|
||||
|
||||
[JsonProperty("className")]
|
||||
public string ClassName { get; set; }
|
||||
|
||||
[JsonProperty("gender")]
|
||||
public string Gender { get; set; }
|
||||
|
||||
[JsonProperty("age")]
|
||||
public int Age { get; set; }
|
||||
|
||||
[JsonProperty("avatar")]
|
||||
public string Avatar { get; set; }
|
||||
}
|
||||
}
|
||||
73
YD_WeChatApplet.Commons/Utils/JSSaTokenSignHelper.cs
Normal file
73
YD_WeChatApplet.Commons/Utils/JSSaTokenSignHelper.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace YD_WeChatApplet.Commons.Utils
|
||||
{
|
||||
public static class SaTokenSignHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据业务参数生成 Java Sa-Token Sign 兼容的 QueryString
|
||||
/// 自动生成 timestamp 和 nonce,如果外部未提供
|
||||
/// </summary>
|
||||
/// <param name="paramMap">业务参数字典(可包含 teacherNo 等)</param>
|
||||
/// <param name="secretKey">应用密钥</param>
|
||||
/// <param name="channel">应用编码,例如 sk-yuedong</param>
|
||||
/// <returns>带 sign 的完整 QueryString</returns>
|
||||
public static string BuildQueryString(Dictionary<string, object> paramMap, string secretKey)
|
||||
{
|
||||
if (paramMap == null)
|
||||
paramMap = new Dictionary<string, object>();
|
||||
|
||||
// 1️⃣ TreeMap 排序(ASCII 升序)
|
||||
var sorted = new SortedDictionary<string, string>(StringComparer.Ordinal);
|
||||
foreach (var kv in paramMap)
|
||||
sorted[kv.Key] = kv.Value.ToString();
|
||||
|
||||
// 2️⃣ 拼接签名字符串 k=v&k=v&...&key=secretKey
|
||||
var sbSign = new StringBuilder();
|
||||
foreach (var kv in sorted)
|
||||
sbSign.Append(kv.Key).Append("=").Append(kv.Value).Append("&");
|
||||
sbSign.Append("key=").Append(secretKey.Trim());
|
||||
|
||||
string sign = Md5(sbSign.ToString());
|
||||
|
||||
// 3️⃣ 拼接 QueryString(保留外部字典原顺序)
|
||||
var sbQuery = new StringBuilder();
|
||||
foreach (var kv in paramMap)
|
||||
sbQuery.Append(Uri.EscapeDataString(kv.Key))
|
||||
.Append("=")
|
||||
.Append(Uri.EscapeDataString(kv.Value.ToString()))
|
||||
.Append("&");
|
||||
|
||||
sbQuery.Append("sign=").Append(sign);
|
||||
|
||||
return sbQuery.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MD5 小写 32 位
|
||||
/// </summary>
|
||||
private static string Md5(string input)
|
||||
{
|
||||
using var md5 = MD5.Create();
|
||||
var bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
|
||||
var sb = new StringBuilder();
|
||||
foreach (var b in bytes)
|
||||
sb.Append(b.ToString("x2"));
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成随机字符串 nonce,可指定长度
|
||||
/// </summary>
|
||||
public static string RandomString(int length = 20)
|
||||
{
|
||||
const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
var random = new Random();
|
||||
return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user