补充本地调试页面入口

This commit is contained in:
zhangshun
2026-06-01 17:25:10 +08:00
parent 2d9bd1d4d7
commit 4c1ec24be8
3 changed files with 348 additions and 2 deletions

335
public/index.html Normal file
View File

@@ -0,0 +1,335 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>smart_wasm Local Debug</title>
<style>
:root {
--bg: #f3efe5;
--panel: #fffaf0;
--line: #d2c7b3;
--text: #1f2a30;
--muted: #6e7a80;
--accent: #0d6b5f;
--accent-2: #d7852f;
--error: #b7402a;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: "Segoe UI", "Microsoft YaHei", sans-serif;
color: var(--text);
background:
radial-gradient(circle at top left, rgba(215, 133, 47, 0.18), transparent 30%),
linear-gradient(135deg, #f7f1e3 0%, #e8efe9 100%);
min-height: 100vh;
}
.shell {
max-width: 1100px;
margin: 0 auto;
padding: 32px 20px 48px;
}
.hero {
display: grid;
gap: 16px;
margin-bottom: 24px;
}
.hero h1 {
margin: 0;
font-size: clamp(28px, 5vw, 48px);
line-height: 1.05;
}
.hero p {
margin: 0;
color: var(--muted);
max-width: 720px;
font-size: 16px;
}
.layout {
display: grid;
grid-template-columns: 1.05fr 0.95fr;
gap: 20px;
}
.card {
background: rgba(255, 250, 240, 0.9);
backdrop-filter: blur(10px);
border: 1px solid var(--line);
border-radius: 20px;
box-shadow: 0 20px 40px rgba(38, 50, 56, 0.08);
overflow: hidden;
}
.card-head {
padding: 18px 20px;
border-bottom: 1px solid var(--line);
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
}
.card-head h2 {
margin: 0;
font-size: 18px;
}
.status {
font-size: 13px;
color: var(--muted);
padding: 6px 10px;
border: 1px solid var(--line);
border-radius: 999px;
background: rgba(255, 255, 255, 0.7);
}
.body {
padding: 20px;
}
label {
display: block;
font-size: 13px;
color: var(--muted);
margin-bottom: 8px;
}
textarea {
width: 100%;
min-height: 320px;
resize: vertical;
border: 1px solid var(--line);
border-radius: 14px;
padding: 14px;
font: 13px/1.5 Consolas, "Courier New", monospace;
color: var(--text);
background: #fff;
}
.actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 16px;
}
button {
border: 0;
border-radius: 12px;
padding: 12px 16px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
}
.primary {
background: var(--accent);
color: #fff;
}
.secondary {
background: #fff;
color: var(--text);
border: 1px solid var(--line);
}
pre {
margin: 0;
min-height: 420px;
padding: 16px;
overflow: auto;
background: #172126;
color: #e8f2ef;
font: 13px/1.5 Consolas, "Courier New", monospace;
}
.tips {
display: grid;
gap: 10px;
margin-top: 18px;
color: var(--muted);
font-size: 13px;
}
.tips code {
color: var(--accent);
}
@media (max-width: 900px) {
.layout {
grid-template-columns: 1fr;
}
textarea,
pre {
min-height: 260px;
}
}
</style>
</head>
<body>
<div class="shell">
<section class="hero">
<h1>smart_wasm 本地调试页</h1>
<p>这个页面直接加载 <code>public/wasm/smart_math.js</code>,可以在本地验证 WASM 初始化、命令调用和返回 JSON。</p>
</section>
<section class="layout">
<div class="card">
<div class="card-head">
<h2>请求</h2>
<div class="status" id="module-status">WASM 未初始化</div>
</div>
<div class="body">
<label for="request">JSON Request</label>
<textarea id="request">{
"msg": "list robots after init",
"req_code": "CASE_LIST_001",
"req_from": "local_debug",
"req_cmd": "Cmd_ListRobots",
"req_param": {}
}</textarea>
<div class="actions">
<button class="primary" id="init-btn" type="button">初始化 WASM</button>
<button class="primary" id="run-btn" type="button">发送请求</button>
<button class="secondary" id="sample-btn" type="button">填充四杆样例</button>
<button class="secondary" id="clear-btn" type="button">清空输出</button>
</div>
<div class="tips">
<div>1. 先点 <code>初始化 WASM</code>,会调用 <code>_init_func()</code></div>
<div>2. 再点 <code>发送请求</code>,会调用 <code>_func()</code></div>
<div>3. 默认地址使用 <code>http://localhost:8080/</code></div>
</div>
</div>
</div>
<div class="card">
<div class="card-head">
<h2>响应</h2>
<div class="status" id="request-status">等待操作</div>
</div>
<pre id="output">No output yet.</pre>
</div>
</section>
</div>
<script src="./wasm/smart_math.js"></script>
<script>
let wasmModule = null;
const moduleStatus = document.getElementById("module-status");
const requestStatus = document.getElementById("request-status");
const requestBox = document.getElementById("request");
const output = document.getElementById("output");
function setOutput(value) {
output.textContent = value;
}
function allocString(value) {
const size = wasmModule.lengthBytesUTF8(value) + 1;
const ptr = wasmModule._malloc(size);
wasmModule.stringToUTF8(value, ptr, size);
return ptr;
}
function sampleFourBar() {
requestBox.value = JSON.stringify({
msg: "fourbar valid",
req_code: "CASE_FB_001",
req_from: "local_debug",
req_cmd: "Cmd_FourBar_CrankSlider",
req_param: {
L_AB: 0.5,
L_BS: 2.0,
S_OFS: 0.0,
angleDeg: 45.0
}
}, null, 2);
}
async function ensureModule() {
if (wasmModule) {
return wasmModule;
}
requestStatus.textContent = "正在加载模块";
wasmModule = await createSmartMathModule();
moduleStatus.textContent = "WASM 已加载";
requestStatus.textContent = "模块加载完成";
return wasmModule;
}
async function initializeBusinessApi() {
const mod = await ensureModule();
let responsePtr = null;
try {
responsePtr = mod._init_func();
const text = mod.UTF8ToString(responsePtr);
setOutput(text);
moduleStatus.textContent = "业务接口已初始化";
requestStatus.textContent = "初始化成功";
} catch (error) {
moduleStatus.textContent = "初始化失败";
requestStatus.textContent = "初始化失败";
setOutput(String(error && error.stack ? error.stack : error));
} finally {
if (responsePtr) {
mod._smart_free_string(responsePtr);
}
}
}
async function runRequest() {
const mod = await ensureModule();
let requestPtr = null;
let responsePtr = null;
try {
const raw = requestBox.value.trim();
JSON.parse(raw);
requestPtr = allocString(raw);
responsePtr = mod._func(requestPtr);
const text = mod.UTF8ToString(responsePtr);
try {
setOutput(JSON.stringify(JSON.parse(text), null, 2));
} catch {
setOutput(text);
}
requestStatus.textContent = "请求成功";
} catch (error) {
requestStatus.textContent = "请求失败";
setOutput(String(error && error.stack ? error.stack : error));
} finally {
if (requestPtr) {
mod._free(requestPtr);
}
if (responsePtr) {
mod._smart_free_string(responsePtr);
}
}
}
document.getElementById("init-btn").addEventListener("click", initializeBusinessApi);
document.getElementById("run-btn").addEventListener("click", runRequest);
document.getElementById("sample-btn").addEventListener("click", sampleFourBar);
document.getElementById("clear-btn").addEventListener("click", () => {
requestStatus.textContent = "等待操作";
setOutput("No output yet.");
});
</script>
</body>
</html>

11
public/smart_test.html Normal file
View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="0; url=./index.html">
<title>Redirecting</title>
</head>
<body>
<p>Redirecting to <a href="./index.html">index.html</a> ...</p>
</body>
</html>

View File

@@ -45,9 +45,9 @@ $publicDir = Resolve-Path "public"
Write-Host "[ ] Starting dev server..." -ForegroundColor Cyan Write-Host "[ ] Starting dev server..." -ForegroundColor Cyan
Write-Host "" Write-Host ""
Write-Host "Server info:" -ForegroundColor White Write-Host "Server info:" -ForegroundColor White
Write-Host " - URL: http://localhost:8080" -ForegroundColor Cyan Write-Host " - URL: http://localhost:8080/index.html" -ForegroundColor Cyan
Write-Host " - Root: $publicDir" -ForegroundColor Gray Write-Host " - Root: $publicDir" -ForegroundColor Gray
Write-Host " - Home: /smart_test.html" -ForegroundColor Gray Write-Host " - Home: /index.html" -ForegroundColor Gray
Write-Host " - Stop: Ctrl+C" -ForegroundColor Yellow Write-Host " - Stop: Ctrl+C" -ForegroundColor Yellow
Write-Host "" Write-Host ""