- YARP: map-edit/ai-config 全方法、reflection 写方法挂 PlatformScope, reflection/selection 单独放行(运营端 3D 高亮),堵住运营账号直达地图编辑/反射调用 - goto-site 探测改用不存在的 car/-1(消除健康检查真实派车风险)并加 60s 缓存 - Config PUT 按 scope 收紧:RCSMonitor 仅可写 ops 节;wizard 写操作与 simplelite/restart-for-update 限 PlatformScope;/api/health 去除虚假端口表 - 修复 wms 模块菜单裁剪失效(admin-config-location → admin-config-facility) - vrHost 默认 location.hostname:8223(新增 utils/vrender.ts),远程访问 3D 视口可用 - /status 页改接真实 /api/health* 诊断;uploadAsset 移除矛盾 multipart 头; mapsApi.merge 对齐 save 的 409 冲突处理;JWT 验签参数改启动期 DI 一次性配置 - 清理死代码:ProjectionController、DataTablePro、useClipboard、CadToolbarView、 AppShell 未用导入;lint 脚本替换为 typecheck;日志窗口 List 改 Queue
128 lines
4.8 KiB
C#
128 lines
4.8 KiB
C#
using System.Diagnostics;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace MiGu.Server.Launcher;
|
|
|
|
/// <summary>
|
|
/// 将 <c>obj/Debug</c> 下最新编译的 SimpleLite 同步到 <c>bin/Debug</c>(仅当 SimpleLite 未运行时)。
|
|
/// </summary>
|
|
public static class SimpleLiteBuildSync
|
|
{
|
|
public static bool TrySyncFromObjToBin(string contentRoot, ILogger? log = null)
|
|
{
|
|
if (!TryResolvePaths(contentRoot, out var objDll, out var objExe, out var binDir))
|
|
return false;
|
|
|
|
var binDll = Path.Combine(binDir, "SimpleLite.dll");
|
|
var binExe = Path.Combine(binDir, "SimpleLite.exe");
|
|
|
|
if (!File.Exists(objDll))
|
|
{
|
|
log?.LogDebug("[SimpleLiteBuildSync] obj DLL 不存在: {Path}", objDll);
|
|
return false;
|
|
}
|
|
|
|
if (Process.GetProcessesByName("SimpleLite").Any(p => !p.HasExited))
|
|
{
|
|
log?.LogWarning("[SimpleLiteBuildSync] SimpleLite 仍在运行,跳过 DLL 同步。请先关闭 SimpleLite 窗口。");
|
|
return false;
|
|
}
|
|
|
|
var objTime = File.GetLastWriteTimeUtc(objDll);
|
|
if (File.Exists(binDll) && File.GetLastWriteTimeUtc(binDll) >= objTime)
|
|
{
|
|
log?.LogDebug("[SimpleLiteBuildSync] bin 已是最新,无需同步");
|
|
return false;
|
|
}
|
|
|
|
Directory.CreateDirectory(binDir);
|
|
File.Copy(objDll, binDll, true);
|
|
log?.LogInformation("[SimpleLiteBuildSync] 已同步 {Src} → {Dst}", objDll, binDll);
|
|
|
|
if (File.Exists(objExe))
|
|
{
|
|
File.Copy(objExe, binExe, true);
|
|
log?.LogInformation("[SimpleLiteBuildSync] 已同步 {Src} → {Dst}", objExe, binExe);
|
|
}
|
|
|
|
SyncRuntimeDeps(objDll, binDir, log);
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 探测 SimpleLite 是否带「前往站点」路由(区分新旧 DLL)。
|
|
/// 必须用不存在的对象 id(-1):路由存在时后端进 handler 找不到对象,返回 JSON
|
|
/// <c>success:false</c>(无任何副作用);路由不存在时 EmbedIO 返回 HTML 404。
|
|
/// 早期版本误用 car/0 + siteId=0 —— 一旦场景里真有 id=0 的车和站点,每次健康
|
|
/// 检查都会真实派车,属严重副作用,严禁回退到真实 id。
|
|
/// </summary>
|
|
public static bool? ProbeGotoSiteRoute(int port = 8222)
|
|
{
|
|
try
|
|
{
|
|
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(2) };
|
|
using var resp = client.PostAsync(
|
|
$"http://127.0.0.1:{port}/projection/reflection/car/-1/goto-site?siteId=-1",
|
|
null).GetAwaiter().GetResult();
|
|
var body = resp.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
|
if (resp.StatusCode == System.Net.HttpStatusCode.NotFound)
|
|
return body.Contains("<html", StringComparison.OrdinalIgnoreCase) ? false : true;
|
|
return body.Contains("\"success\"", StringComparison.Ordinal);
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>同步 obj 输出目录中的运行时依赖(Costura 未嵌入或需独立存在的 DLL)。</summary>
|
|
private static void SyncRuntimeDeps(string objDll, string binDir, ILogger? log)
|
|
{
|
|
var objDir = Path.GetDirectoryName(objDll);
|
|
if (string.IsNullOrEmpty(objDir)) return;
|
|
|
|
var names = new[] { "LessokajiWeaverUtilities.dll" };
|
|
foreach (var name in names)
|
|
{
|
|
var src = Path.Combine(objDir, name);
|
|
if (!File.Exists(src))
|
|
{
|
|
var deps = Path.Combine(objDir, "..", "..", "tools", "deps", name);
|
|
deps = Path.GetFullPath(deps);
|
|
if (File.Exists(deps)) src = deps;
|
|
else continue;
|
|
}
|
|
|
|
var dst = Path.Combine(binDir, name);
|
|
File.Copy(src, dst, true);
|
|
log?.LogInformation("[SimpleLiteBuildSync] 已同步依赖 {Name}", name);
|
|
}
|
|
}
|
|
|
|
private static bool TryResolvePaths(string contentRoot, out string objDll, out string objExe, out string binDir)
|
|
{
|
|
objDll = objExe = "";
|
|
binDir = "";
|
|
var repo = FindRepoRoot(contentRoot);
|
|
if (repo == null) return false;
|
|
var sl = Path.Combine(repo, "Simple", "SimpleLite");
|
|
objDll = Path.Combine(sl, "obj", "Debug", "SimpleLite.dll");
|
|
objExe = Path.Combine(sl, "obj", "Debug", "SimpleLite.exe");
|
|
binDir = Path.Combine(sl, "bin", "Debug");
|
|
return true;
|
|
}
|
|
|
|
private static string? FindRepoRoot(string contentRoot)
|
|
{
|
|
var dir = new DirectoryInfo(contentRoot);
|
|
while (dir != null)
|
|
{
|
|
if (Directory.Exists(Path.Combine(dir.FullName, "Simple", "SimpleLite")))
|
|
return dir.FullName;
|
|
dir = dir.Parent;
|
|
}
|
|
return null;
|
|
}
|
|
}
|