bag
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
// SchClass OpenAPI 调试入口:独立控制台,不开测试即可联调教务后端。
|
||||
//
|
||||
// 用法:
|
||||
// dotnet run --project samples/Yh.SchClass.DebugTool # 跑全部 20 个端点
|
||||
// dotnet run --project samples/Yh.SchClass.DebugTool -- --list # 只列出端点名
|
||||
// dotnet run --project samples/Yh.SchClass.DebugTool -- --only=OAStu
|
||||
// dotnet run --project samples/Yh.SchClass.DebugTool -- --host=http://192.168.1.20:8080 --path=/bschclass
|
||||
// 可覆盖项:--host --path --sch --class --tea --group --only
|
||||
//
|
||||
// 地址优先级:命令行参数 → 环境变量 YH_SCHCLASS_DEBUG_* → appsettings.json(yh:schclass:open → yh:open)→ 内置默认。
|
||||
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Yh.SchClass.OpenApi;
|
||||
|
||||
Console.OutputEncoding = Encoding.UTF8;
|
||||
|
||||
const string DefaultHost = "http://base.yunhaixingtong.com";
|
||||
const string DefaultPath = "/bschclass";
|
||||
|
||||
string? host = null, path = null, sch = null, classId = null, teaRaw = null, groupRaw = null, only = null;
|
||||
bool listOnly = false;
|
||||
|
||||
// 环境变量兜底(与测试工程的 SchClassLiveDebug 同名同义)
|
||||
string? Env(string n) { var v = Environment.GetEnvironmentVariable(n); return string.IsNullOrWhiteSpace(v) ? null : v.Trim(); }
|
||||
host = Env("YH_SCHCLASS_DEBUG_HOST");
|
||||
path = Env("YH_SCHCLASS_DEBUG_PATH");
|
||||
sch = Env("YH_SCHCLASS_DEBUG_SCH");
|
||||
classId = Env("YH_SCHCLASS_DEBUG_CLASS");
|
||||
teaRaw = Env("YH_SCHCLASS_DEBUG_TEA");
|
||||
groupRaw = Env("YH_SCHCLASS_DEBUG_GROUP");
|
||||
|
||||
// 命令行参数优先
|
||||
foreach (var arg in args)
|
||||
{
|
||||
if (!arg.StartsWith("--")) { continue; }
|
||||
var kv = arg[2..].Split('=', 2);
|
||||
var key = kv[0].Trim().ToLowerInvariant();
|
||||
var val = kv.Length > 1 ? kv[1].Trim() : null;
|
||||
switch (key)
|
||||
{
|
||||
case "host": host = val; break;
|
||||
case "path": path = val; break;
|
||||
case "sch": sch = val; break;
|
||||
case "class": classId = val; break;
|
||||
case "tea": teaRaw = val; break;
|
||||
case "group": groupRaw = val; break;
|
||||
case "only": only = val; break;
|
||||
case "list": listOnly = true; break;
|
||||
}
|
||||
}
|
||||
|
||||
var config = new ConfigurationBuilder()
|
||||
.SetBasePath(AppContext.BaseDirectory)
|
||||
.AddJsonFile("appsettings.json", optional: true)
|
||||
.Build();
|
||||
host ??= config["yh:schclass:open:BaseHost"] ?? config["yh:open:BaseHost"] ?? DefaultHost;
|
||||
path ??= config["yh:schclass:open:BasePath"] ?? config["yh:open:SchClassPath"] ?? DefaultPath;
|
||||
|
||||
var options = new SchClassOpenApiOptions { BaseHost = host, BasePath = string.IsNullOrWhiteSpace(path) ? null : path };
|
||||
var api = SchClassOpenApiFactory.Create(options);
|
||||
|
||||
// ---- 构造调试用例(缺省 ID 一律从真实数据推导,避免捏造 ID 造成假 0 条) ----
|
||||
var group = int.TryParse(groupRaw, out var g) ? g : 3;
|
||||
var teaId = int.TryParse(teaRaw, out var t) ? t : 0;
|
||||
|
||||
Console.WriteLine($"目标:{options.ResolveBaseUrl()}");
|
||||
|
||||
// --list:只打印端点名,不做任何网络请求
|
||||
if (listOnly)
|
||||
{
|
||||
foreach (var name in new[]
|
||||
{
|
||||
"DbClass.GetSchteaList", "VSchClass.GetVClassList", "VSchClass.GetSchArrVClassListAll",
|
||||
"VSchClass.GetSchArrVClassListPost", "Schoolen.GetSchLenLevellist", "Schoolen.GetSchLenlist",
|
||||
"UserInfo.GetUserList", "SchInfo.AllList", "SchInfo.GetSchlist", "OATea.GetSchTeainfo",
|
||||
"OATea.GetArrTeainfo", "OAStu.GetAllStulist", "OAStu.GetSchStulist", "OAStu.GetClaStulist",
|
||||
"TeachInfo.GetSchTeachlist", "TeachInfo.GetSchClaTeachlist", "SubInfo.GetSchTeachSublist",
|
||||
"SubInfo.GetSchSublist", "FamCom.GetStuUserFamIDList", "FamCom.GetAllStuFamMem",
|
||||
})
|
||||
{
|
||||
Console.WriteLine(name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
var schResolved = sch;
|
||||
var cases = new List<(string Name, Func<Task<int>> Call)>();
|
||||
|
||||
// 先探测学校列表,推导缺省参数
|
||||
try
|
||||
{
|
||||
var schools = await api.SchInfo.AllListAsync();
|
||||
Console.WriteLine($"学校列表:{schools.Count} 所(前 3:{string.Join(" | ", schools.Take(3).Select(s => $"{s.SchName}[{s.SchSerId}]"))})");
|
||||
schResolved ??= schools.FirstOrDefault()?.SchSerId ?? "S001";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"!! 学校列表探测失败:{e.GetType().Name}: {e.Message}");
|
||||
Console.WriteLine("后端不可达时后续端点大概率全部失败,仍继续逐个执行以便核对。");
|
||||
schResolved ??= "S001";
|
||||
}
|
||||
|
||||
if (!listOnly)
|
||||
{
|
||||
var sch2 = schResolved;
|
||||
string cid = classId ?? "";
|
||||
if (cid.Length == 0)
|
||||
{
|
||||
var cls = (await api.VClass.GetVClassListAsync(sch2)).FirstOrDefault();
|
||||
cid = cls != null && cls.TryGetValue("ClassID", out var c) ? c.ToString() ?? "1001" : "1001";
|
||||
}
|
||||
if (teaId == 0)
|
||||
{
|
||||
var tea = (await api.DbClass.GetSchteaListAsync(group)).FirstOrDefault();
|
||||
teaId = tea != null && tea.TryGetValue("UserTeaSerID", out var d) && int.TryParse(d.ToString(), out var p) ? p : 77;
|
||||
}
|
||||
|
||||
Console.WriteLine($"参数:sch={sch2} classId={cid} teaId={teaId} group={group}");
|
||||
|
||||
cases.Add(("DbClass.GetSchteaList", async () => (await api.DbClass.GetSchteaListAsync(group)).Count));
|
||||
cases.Add(("VSchClass.GetVClassList", async () => (await api.VClass.GetVClassListAsync(sch2)).Count));
|
||||
cases.Add(("VSchClass.GetSchArrVClassListAll", async () => (await api.VClass.GetSchArrVClassListAllAsync()).Count));
|
||||
cases.Add(("VSchClass.GetSchArrVClassListPost", async () => (await api.VClass.GetSchArrVClassListPostAsync(sch2)).Count));
|
||||
cases.Add(("Schoolen.GetSchLenLevellist", async () => (await api.Schooling.GetSchLenLevelListAsync(sch2)).Count));
|
||||
cases.Add(("Schoolen.GetSchLenlist", async () => (await api.Schooling.GetSchLenListAsync(sch2)).Count));
|
||||
cases.Add(("UserInfo.GetUserList", async () => (await api.UserInfo.GetUserListAsync(sch2)).Count));
|
||||
cases.Add(("SchInfo.AllList", async () => (await api.SchInfo.AllListAsync()).Count));
|
||||
cases.Add(("SchInfo.GetSchlist", async () => (await api.SchInfo.GetSchListAsync(null)).Count));
|
||||
cases.Add(("OATea.GetSchTeainfo", async () => (await api.TeaInfo.GetSchTeaInfoAsync(sch2, null)).Count));
|
||||
cases.Add(("OATea.GetArrTeainfo", async () => (await api.TeaInfo.GetArrTeaInfoAsync(teaId.ToString())).Count));
|
||||
cases.Add(("OAStu.GetAllStulist", async () => (await api.StuInfo.GetAllStuListAsync()).Count));
|
||||
cases.Add(("OAStu.GetSchStulist", async () => (await api.StuInfo.GetSchStuListAsync(sch2, null)).Count));
|
||||
cases.Add(("OAStu.GetClaStulist", async () => (await api.StuInfo.GetClaStuListAsync(cid, null)).Count));
|
||||
cases.Add(("TeachInfo.GetSchTeachlist", async () => (await api.TeachInfo.GetSchTeachListAsync(sch2, teaId)).Count));
|
||||
cases.Add(("TeachInfo.GetSchClaTeachlist", async () => (await api.TeachInfo.GetSchClaTeachListAsync(cid)).Count));
|
||||
cases.Add(("SubInfo.GetSchTeachSublist", async () => (await api.SubInfo.GetSchTeachSubListAsync(sch2)).Count));
|
||||
cases.Add(("SubInfo.GetSchSublist", async () => (await api.SubInfo.GetSchSubListAsync(sch2, null, null)).Count));
|
||||
cases.Add(("FamCom.GetStuUserFamIDList", async () => (await api.FamilyCompat.GetStuUserFamIdListAsync("1,2")).Count));
|
||||
cases.Add(("FamCom.GetAllStuFamMem", async () => (await api.FamilyCompat.GetAllStuFamMemAsync("1,2")).Count));
|
||||
}
|
||||
|
||||
var failures = new List<string>();
|
||||
if (only != null)
|
||||
{
|
||||
cases = cases.Where(c => c.Name.Contains(only, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
if (cases.Count == 0)
|
||||
{
|
||||
Console.WriteLine($"--only={only} 未匹配任何端点(用 --list 查看全部名称)");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var (name, call) in cases)
|
||||
{
|
||||
try
|
||||
{
|
||||
var count = await call();
|
||||
Console.WriteLine($" OK {name} -> {count} 条");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
failures.Add(name);
|
||||
Console.WriteLine($" FAIL {name} -> {e.GetType().Name}: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"汇总:{cases.Count - failures.Count}/{cases.Count} 通过");
|
||||
return failures.Count == 0 ? 0 : 1;
|
||||
@@ -0,0 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<IsPackable>false</IsPackable>
|
||||
<RootNamespace>Yh.SchClass.DebugTool</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Yh.SchClass.OpenApi\Yh.SchClass.OpenApi.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="appsettings.json" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"yh": {
|
||||
"open": {
|
||||
"Enabled": true,
|
||||
"BaseHost": "http://base.yunhaixingtong.com",
|
||||
"BasePath": "/userbase",
|
||||
"SchClassPath": "/bschclass",
|
||||
"AppKey": "100002",
|
||||
"AppSecret": "2314a3b158b24a838b2b9b69fd3db118"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user