Phase 3: PluginWebMixin SDK + web plugin control panels

- New: sdk/plugin_web.py (PluginWebMixin: web pages, API routes, SSE)
- New: services/web_panel/routes/plugin_web.py (3 endpoints)
- New: plugins/example_plugin/dashboard.html (counter + SSE demo)
- Updated: example_plugin uses PluginWebMixin
- Tests: 28/28 passing
This commit is contained in:
2026-06-10 20:54:11 +08:00
parent c680fea8e0
commit e52f7f3566
7 changed files with 155 additions and 12 deletions
@@ -0,0 +1,12 @@
<!DOCTYPE html><html lang="zh"><head><meta charset="UTF-8"><title>Example Plugin</title>
<style>body{font-family:monospace;background:#0e1416;color:#e0e3e4;padding:16px}
h2{color:#00bcd4}.card{background:#1a1f21;border-radius:8px;padding:12px;margin:8px 0}
button{background:#00bcd4;color:#000;padding:8px 16px;border:none;border-radius:4px;cursor:pointer}
.counter{font-size:48px;color:#4caf50;text-align:center;padding:20px}
.log{background:#000;color:#0f0;padding:8px;border-radius:4px;max-height:200px;overflow-y:auto;font-size:12px}
</style></head><body>
<h2>Example Plugin Panel</h2>
<div class="card"><h3>Counter</h3><div class="counter" id="count">0</div>
<button onclick="inc()">+1</button> <button onclick="reset()">Reset</button></div>
<div class="card"><h3>Events (SSE)</h3><div class="log" id="log">Waiting...</div></div>
<script>let n=0;function inc(){n++;document.getElementById("count").textContent=n;fetch("/SenSu/plugin/example_plugin/event",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:"counter",value:n})})}function reset(){n=0;document.getElementById("count").textContent=0}const es=new EventSource("/SenSu/plugin/example_plugin/sse");es.addEventListener("counter",e=>{const d=JSON.parse(e.data);document.getElementById("log").innerHTML+=new Date().toLocaleTimeString()+" counter="+d.value+"<br>"})</script></body></html>