first commit
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>江北的渔夫的空间</title>
|
||||
<meta name="description" content="江北的渔夫的空间 —— 工业软件、标准件库与数字化实践分享">
|
||||
<meta name="keywords" content="江北的渔夫的空间, Easy Data Collector, ResLib, 资源中心管理器, Creo, 标准零部件库, 数字孪生">
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="icon" href="/static/img/logo.svg" type="image/svg+xml">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="brand" href="/">
|
||||
<img src="/static/img/logo.svg" alt="Easy Data Collector">
|
||||
<span class="brand-name">Easy Data Collector</span>
|
||||
</a>
|
||||
<nav class="main-nav" id="mainNav">
|
||||
<a href="/">博客</a>
|
||||
<a href="/reslib/">ResLib</a>
|
||||
<a href="/reslib/apply">申请 License</a>
|
||||
<a href="/reslib/status">查询 / 下载</a>
|
||||
<a href="/reslib/package">资源包获取</a>
|
||||
<a href="https://ec.sincos.cc">Engineer Craft</a>
|
||||
<a href="https://dt.sincos.cc">Digital Twin</a>
|
||||
<a href="https://neural.sincos.cc">Neural Research</a>
|
||||
<a href="https://git.sincos.cc">Gitea Project</a>
|
||||
</nav>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="section">
|
||||
<div class="container narrow">
|
||||
<h2 class="section-title">关于</h2>
|
||||
<div class="article">
|
||||
<h3>SinCos</h3>
|
||||
<p>工业软件方向开发者。</p>
|
||||
<h3>正在做</h3>
|
||||
<ul>
|
||||
<li><b>ResLib</b>:资源中心管理器 —— Creo 7.0+ 标准零部件管理库(Pro/TOOLKIT DLL 插件),支持 License 在线申请与审批</li>
|
||||
<li><b>Engineer Craft</b>:工程实践与工艺设计平台</li>
|
||||
<li><b>Digital Twin</b>:数字孪生平台(three.js + Python + MQTT/EMQX)</li>
|
||||
<li><b>Neural Research</b>:神经网络与算法研究</li>
|
||||
<li><b>Gitea Project</b>:代码托管与版本管理</li>
|
||||
</ul>
|
||||
<h3>联系方式</h3>
|
||||
<ul>
|
||||
<li>博客:<a href="/">sincos.cc</a></li>
|
||||
<li>License 申请:<a href="/reslib/apply">/reslib/apply</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container footer-inner">
|
||||
<span>Copyright © 2026 Easy Data Collector. All rights reserved.</span>
|
||||
<span><a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">苏ICP备2026056863号</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/static/js/nav.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,233 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>管理后台 - ResLib License</title>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="icon" href="/static/img/logo.svg" type="image/svg+xml">
|
||||
<style>
|
||||
.filters { display: flex; gap: 8px; flex-wrap: wrap; margin: 18px 0; }
|
||||
.filter-btn {
|
||||
padding: 6px 16px; border-radius: 20px; border: 1px solid var(--line);
|
||||
background: #fff; color: var(--ink-light); font-size: 0.85rem; cursor: pointer; font-family: inherit;
|
||||
}
|
||||
.filter-btn.active { background: var(--blue); color: #fff; border-color: var(--blue); }
|
||||
.empty { text-align: center; color: var(--ink-light); padding: 40px 0; }
|
||||
|
||||
.modal-mask {
|
||||
position: fixed; inset: 0; background: rgba(15, 30, 50, 0.5);
|
||||
display: none; align-items: center; justify-content: center; z-index: 200; padding: 20px;
|
||||
}
|
||||
.modal-mask.show { display: flex; }
|
||||
.modal {
|
||||
background: #fff; border-radius: 10px; width: 100%; max-width: 560px;
|
||||
max-height: 90vh; overflow: auto; padding: 26px;
|
||||
}
|
||||
.modal h3 { color: var(--blue-dark); margin-bottom: 14px; }
|
||||
.kv { display: grid; grid-template-columns: 110px 1fr; gap: 8px 12px; font-size: 0.92rem; margin-bottom: 16px; }
|
||||
.kv dt { color: var(--ink-light); }
|
||||
.kv dd { word-break: break-all; }
|
||||
.lic-preview {
|
||||
background: #0d2b4a; color: #7cc0ff; font-family: Consolas, monospace;
|
||||
border-radius: 6px; padding: 12px 14px; font-size: 0.85rem; margin: 12px 0; letter-spacing: 0.05em;
|
||||
}
|
||||
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 18px; flex-wrap: wrap; }
|
||||
.deny-reason { width: 100%; margin-top: 10px; display: none; }
|
||||
.deny-reason.show { display: block; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="brand" href="/admin">
|
||||
<img src="/static/img/logo.svg" alt="ResLib">
|
||||
<span class="brand-name">ResLib License 管理后台</span>
|
||||
</a>
|
||||
<div>
|
||||
<a href="/reslib/" class="btn btn-ghost btn-sm" style="margin-right:8px;">前台</a>
|
||||
<a href="/admin/logout" class="btn btn-danger btn-sm">退出</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="section" style="padding-top: 30px;">
|
||||
<div class="container">
|
||||
<div class="filters" id="filters">
|
||||
<button class="filter-btn active" data-f="all">全部</button>
|
||||
<button class="filter-btn" data-f="pending">待审核</button>
|
||||
<button class="filter-btn" data-f="approved">已批准</button>
|
||||
<button class="filter-btn" data-f="denied">已拒绝</button>
|
||||
<button id="refresh" class="filter-btn" style="margin-left:auto; border-color: var(--blue); color: var(--blue);">刷新</button>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table class="admin" id="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>申请编号</th><th>提交时间</th><th>公司</th><th>联系人</th><th>邮箱</th>
|
||||
<th>MAC</th><th>状态</th><th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="empty" id="empty" style="display:none;">暂无申请记录</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="modal-mask" id="mask">
|
||||
<div class="modal">
|
||||
<h3 id="m-title">申请详情</h3>
|
||||
<dl class="kv" id="m-body"></dl>
|
||||
<div id="m-lic"></div>
|
||||
<div class="deny-reason" id="deny-box">
|
||||
<label style="font-size:0.85rem; font-weight:600;">拒绝原因(可选):</label>
|
||||
<input type="text" id="deny-reason-input" style="width:100%; margin-top:6px; padding:9px 12px; border:1px solid #cfdcea; border-radius:6px;">
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button class="btn btn-ghost btn-sm" id="m-close">关闭</button>
|
||||
<button class="btn btn-danger btn-sm" id="m-deny" style="display:none;">拒绝</button>
|
||||
<button class="btn btn-primary btn-sm" id="m-approve" style="display:none;">批准并生成 License</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var tbody = document.getElementById("tbody");
|
||||
var empty = document.getElementById("empty");
|
||||
var filter = "all";
|
||||
var items = [];
|
||||
var current = null;
|
||||
|
||||
function badge(s) {
|
||||
if (s === "approved") return '<span class="badge badge-approved">已批准</span>';
|
||||
if (s === "denied") return '<span class="badge badge-denied">已拒绝</span>';
|
||||
return '<span class="badge badge-pending">待审核</span>';
|
||||
}
|
||||
|
||||
async function load() {
|
||||
try {
|
||||
var resp = await fetch("/api/admin/list");
|
||||
if (resp.status === 401) { window.location.href = "/admin/login"; return; }
|
||||
items = await resp.json();
|
||||
render();
|
||||
} catch (e) {
|
||||
alert("加载失败:" + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
function render() {
|
||||
var list = filter === "all" ? items : items.filter(function (i) { return i.status === filter; });
|
||||
tbody.innerHTML = "";
|
||||
empty.style.display = list.length ? "none" : "block";
|
||||
list.forEach(function (i) {
|
||||
var tr = document.createElement("tr");
|
||||
tr.innerHTML =
|
||||
'<td class="mono">' + i.id + "</td>" +
|
||||
"<td>" + i.created + "</td>" +
|
||||
"<td>" + esc(i.company) + "</td>" +
|
||||
"<td>" + esc(i.contact) + "</td>" +
|
||||
"<td>" + esc(i.email) + "</td>" +
|
||||
'<td class="mono">' + esc(i.mac) + "</td>" +
|
||||
"<td>" + badge(i.status) + "</td>" +
|
||||
'<td class="actions"><button class="btn btn-ghost btn-sm" data-view="' + i.id + '">详情</button></td>';
|
||||
tbody.appendChild(tr);
|
||||
});
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
return String(s == null ? "" : s).replace(/[&<>"']/g, function (c) {
|
||||
return { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[c];
|
||||
});
|
||||
}
|
||||
|
||||
function showDetail(id) {
|
||||
current = items.find(function (i) { return i.id === id; });
|
||||
if (!current) return;
|
||||
document.getElementById("m-body").innerHTML =
|
||||
"<dt>申请编号</dt><dd class='mono'>" + current.id + "</dd>" +
|
||||
"<dt>提交时间</dt><dd>" + current.created + "</dd>" +
|
||||
"<dt>状态</dt><dd>" + badge(current.status) + "</dd>" +
|
||||
"<dt>MAC 地址</dt><dd class='mono'>" + esc(current.mac) + "</dd>" +
|
||||
"<dt>公司</dt><dd>" + esc(current.company) + "</dd>" +
|
||||
"<dt>联系人</dt><dd>" + esc(current.contact) + "</dd>" +
|
||||
"<dt>邮箱</dt><dd>" + esc(current.email) + "</dd>" +
|
||||
"<dt>Creo 版本</dt><dd>" + esc(current.creo) + "</dd>" +
|
||||
"<dt>授权套数</dt><dd>" + esc(current.seats) + "</dd>" +
|
||||
"<dt>备注</dt><dd>" + esc(current.notes) || "(无)" + "</dd>" +
|
||||
(current.reason ? "<dt>拒绝原因</dt><dd>" + esc(current.reason) + "</dd>" : "");
|
||||
|
||||
var licBox = document.getElementById("m-lic");
|
||||
licBox.innerHTML = "";
|
||||
if (current.status === "approved") {
|
||||
licBox.innerHTML =
|
||||
"<b style='font-size:0.88rem;'>已生成授权文件:</b>" +
|
||||
"<div class='lic-preview' id='lic-content'></div>" +
|
||||
"<a class='btn btn-primary btn-sm' href='/api/license/" + encodeURIComponent(current.id) + "' download>下载 res_center.lic</a>";
|
||||
fetch("/api/license/" + encodeURIComponent(current.id)).then(function (r) { return r.text(); }).then(function (t) {
|
||||
var el = document.getElementById("lic-content");
|
||||
if (el) el.textContent = t.trim();
|
||||
}).catch(function () {});
|
||||
}
|
||||
|
||||
document.getElementById("m-approve").style.display =
|
||||
current.status === "pending" ? "" : "none";
|
||||
document.getElementById("m-deny").style.display =
|
||||
current.status === "pending" ? "" : "none";
|
||||
document.getElementById("deny-box").classList.remove("show");
|
||||
document.getElementById("deny-reason-input").value = "";
|
||||
document.getElementById("mask").classList.add("show");
|
||||
}
|
||||
|
||||
document.getElementById("filters").addEventListener("click", function (e) {
|
||||
var b = e.target.closest(".filter-btn");
|
||||
if (!b || b.id === "refresh") return;
|
||||
document.querySelectorAll(".filter-btn").forEach(function (x) { x.classList.remove("active"); });
|
||||
b.classList.add("active");
|
||||
filter = b.dataset.f;
|
||||
render();
|
||||
});
|
||||
|
||||
document.getElementById("refresh").addEventListener("click", load);
|
||||
|
||||
tbody.addEventListener("click", function (e) {
|
||||
var b = e.target.closest("[data-view]");
|
||||
if (b) showDetail(b.dataset.view);
|
||||
});
|
||||
|
||||
document.getElementById("m-close").addEventListener("click", function () {
|
||||
document.getElementById("mask").classList.remove("show");
|
||||
});
|
||||
document.getElementById("mask").addEventListener("click", function (e) {
|
||||
if (e.target === this) this.classList.remove("show");
|
||||
});
|
||||
|
||||
document.getElementById("m-approve").addEventListener("click", async function () {
|
||||
if (!confirm("确认批准该申请并生成 License?")) return;
|
||||
var resp = await fetch("/api/admin/approve/" + encodeURIComponent(current.id), { method: "POST" });
|
||||
if (resp.ok) { closeAndReload(); } else { alert("操作失败"); }
|
||||
});
|
||||
|
||||
document.getElementById("m-deny").addEventListener("click", async function () {
|
||||
if (!confirm("确认拒绝该申请?")) return;
|
||||
var reason = document.getElementById("deny-reason-input").value;
|
||||
var resp = await fetch("/api/admin/deny/" + encodeURIComponent(current.id), {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: "reason=" + encodeURIComponent(reason)
|
||||
});
|
||||
if (resp.ok) { closeAndReload(); } else { alert("操作失败"); }
|
||||
});
|
||||
|
||||
function closeAndReload() {
|
||||
document.getElementById("mask").classList.remove("show");
|
||||
load();
|
||||
}
|
||||
|
||||
load();
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>管理登录 - ResLib License</title>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="icon" href="/static/img/logo.svg" type="image/svg+xml">
|
||||
</head>
|
||||
<body style="background: #f4f8fd;">
|
||||
|
||||
<main style="display:flex; align-items:center; justify-content:center; min-height:100vh;">
|
||||
<div style="width:100%; max-width:360px; padding:0 20px;">
|
||||
<div style="text-align:center; margin-bottom:22px;">
|
||||
<img src="/static/img/logo.svg" alt="ResLib" style="width:48px; height:48px;">
|
||||
<h1 style="font-size:1.25rem; color:var(--blue-dark); margin-top:10px;">ResLib License 管理后台</h1>
|
||||
</div>
|
||||
<div class="form-card" style="margin-top:0;">
|
||||
<div class="form-group">
|
||||
<label for="password">管理密码</label>
|
||||
<input type="password" id="password" autocomplete="current-password">
|
||||
</div>
|
||||
<button type="button" id="login" class="btn btn-primary btn-block">登 录</button>
|
||||
<div id="result"></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var btn = document.getElementById("login");
|
||||
var result = document.getElementById("result");
|
||||
|
||||
btn.addEventListener("click", async function () {
|
||||
var password = document.getElementById("password").value;
|
||||
btn.disabled = true;
|
||||
btn.textContent = "登录中…";
|
||||
try {
|
||||
var resp = await fetch("/api/admin/login", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: "password=" + encodeURIComponent(password)
|
||||
});
|
||||
var data = await resp.json();
|
||||
if (resp.ok) {
|
||||
window.location.href = "/admin";
|
||||
} else {
|
||||
result.className = "alert show alert-err";
|
||||
result.textContent = data.detail || "登录失败";
|
||||
}
|
||||
} catch (e) {
|
||||
result.className = "alert show alert-err";
|
||||
result.textContent = "网络错误:" + e.message;
|
||||
}
|
||||
btn.disabled = false;
|
||||
btn.textContent = "登 录";
|
||||
});
|
||||
|
||||
document.getElementById("password").addEventListener("keydown", function (e) {
|
||||
if (e.key === "Enter") btn.click();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,140 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>申请 License - 江北的渔夫的空间</title>
|
||||
<meta name="description" content="ResLib 资源中心管理器 License 申请:填写 MAC 地址、公司与联系方式,审核通过后下载 res_center.lic 授权文件。">
|
||||
<meta name="keywords" content="江北的渔夫的空间, ResLib, License, MAC 地址, 授权">
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="icon" href="/static/img/logo.svg" type="image/svg+xml">
|
||||
<script src="/static/js/nav.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="brand" href="/reslib/">
|
||||
<img src="/static/img/logo.svg" alt="Easy Data Collector">
|
||||
<span class="brand-name">Easy Data Collector</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="/blog/">博客</a>
|
||||
<a href="/reslib/">ResLib</a>
|
||||
<a href="/reslib/apply" class="active">申请 License</a>
|
||||
<a href="/reslib/status">查询 / 下载</a>
|
||||
<a href="/reslib/package">资源包获取</a>
|
||||
<a href="https://ec.sincos.cc">Engineer Craft</a>
|
||||
<a href="https://dt.sincos.cc">Digital Twin</a>
|
||||
<a href="https://neural.sincos.cc">Neural Research</a>
|
||||
<a href="https://git.sincos.cc">Gitea Project</a>
|
||||
</nav>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="section">
|
||||
<div class="container narrow">
|
||||
<h2 class="section-title">申请 License</h2>
|
||||
<p class="section-desc">提交后我们会进行人工审核,审核通过后凭申请编号下载授权文件。</p>
|
||||
|
||||
<div class="form-card">
|
||||
<div class="form-group">
|
||||
<label for="mac">本机 MAC 地址 *</label>
|
||||
<input type="text" id="mac" class="mono" placeholder="如:AA-BB-CC-DD-EE-FF" maxlength="17" autocomplete="off">
|
||||
<p class="form-hint">如何获取:cmd 运行 <span class="mono">getmac /v</span>,取"物理地址"列(12 位十六进制)。</p>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="company">公司 / 单位名称 *</label>
|
||||
<input type="text" id="company" placeholder="如:某某机械制造有限公司">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="contact">联系人 *</label>
|
||||
<input type="text" id="contact" placeholder="您的姓名">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="email">邮箱 *</label>
|
||||
<input type="email" id="email" placeholder="用于接收 License 相关信息">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="creo">Creo 版本</label>
|
||||
<select id="creo">
|
||||
<option value="Creo 7.0">Creo 7.0</option>
|
||||
<option value="Creo 8.0" selected>Creo 8.0</option>
|
||||
<option value="Creo 9.0">Creo 9.0</option>
|
||||
<option value="Creo 10.0">Creo 10.0</option>
|
||||
<option value="其他">其他</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="seats">授权数量(套)</label>
|
||||
<input type="number" id="seats" min="1" value="1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="notes">备注</label>
|
||||
<textarea id="notes" rows="3" placeholder="选填:使用场景、部门规模等"></textarea>
|
||||
</div>
|
||||
<button type="button" id="submit" class="btn btn-primary btn-block">提交申请</button>
|
||||
<div id="result"></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container footer-inner">
|
||||
<span>Copyright © 2026 SinCos. All rights reserved.</span>
|
||||
<span><a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">苏ICP备2026056863号</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var btn = document.getElementById("submit");
|
||||
var result = document.getElementById("result");
|
||||
|
||||
function show(ok, html) {
|
||||
result.className = "alert show " + (ok ? "alert-ok" : "alert-err");
|
||||
result.innerHTML = html;
|
||||
}
|
||||
|
||||
btn.addEventListener("click", async function () {
|
||||
var payload = {
|
||||
mac: document.getElementById("mac").value,
|
||||
company: document.getElementById("company").value,
|
||||
contact: document.getElementById("contact").value,
|
||||
email: document.getElementById("email").value,
|
||||
creo: document.getElementById("creo").value,
|
||||
seats: document.getElementById("seats").value,
|
||||
notes: document.getElementById("notes").value
|
||||
};
|
||||
btn.disabled = true;
|
||||
btn.textContent = "提交中…";
|
||||
try {
|
||||
var resp = await fetch("/api/apply", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
var data = await resp.json();
|
||||
if (resp.ok) {
|
||||
show(true,
|
||||
"申请已提交成功!<br><b>申请编号:<span class='mono'>" + data.id + "</span></b><br>" +
|
||||
"请妥善保存编号,审核通过后凭编号到 <a href='/reslib/status'>查询 / 下载</a> 页面获取授权文件。");
|
||||
} else {
|
||||
show(false, "提交失败:" + (data.detail || "未知错误"));
|
||||
}
|
||||
} catch (e) {
|
||||
show(false, "网络错误:" + e.message);
|
||||
}
|
||||
btn.disabled = false;
|
||||
btn.textContent = "提交申请";
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>博客开张 - 江北的渔夫的空间</title>
|
||||
<meta name="description" content="江北的渔夫的空间 —— 工业软件、标准件库与数字化实践分享">
|
||||
<meta name="keywords" content="江北的渔夫的空间, Easy Data Collector, ResLib, 资源中心管理器, Creo, 标准零部件库, 数字孪生">
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="icon" href="/static/img/logo.svg" type="image/svg+xml">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="brand" href="/">
|
||||
<img src="/static/img/logo.svg" alt="Easy Data Collector">
|
||||
<span class="brand-name">Easy Data Collector</span>
|
||||
</a>
|
||||
<nav class="main-nav" id="mainNav">
|
||||
<a href="/">博客</a>
|
||||
<a href="/reslib/">ResLib</a>
|
||||
<a href="/reslib/apply">申请 License</a>
|
||||
<a href="/reslib/status">查询 / 下载</a>
|
||||
<a href="/reslib/package">资源包获取</a>
|
||||
<a href="https://ec.sincos.cc">Engineer Craft</a>
|
||||
<a href="https://dt.sincos.cc">Digital Twin</a>
|
||||
<a href="https://neural.sincos.cc">Neural Research</a>
|
||||
<a href="https://git.sincos.cc">Gitea Project</a>
|
||||
</nav>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="section">
|
||||
<div class="container narrow">
|
||||
<nav class="breadcrumb"><a href="/">博客</a> / <a href="/blog/">文章列表</a></nav>
|
||||
<h2 class="section-title">博客开张</h2>
|
||||
<div class="post-meta"><span class="post-date">2026年08月13日</span><span class="tag">公告</span><span class="tag">ResLib</span><span class="tag">数字孪生</span></div>
|
||||
<article class="article">
|
||||
<h1 id="_1">博客开张</h1>
|
||||
<p>用统一风格搭建的聚合博客正式上线,部署在 sincos.cc。</p>
|
||||
<p>本站主要记录:</p>
|
||||
<ul>
|
||||
<li><strong>工业软件</strong>:Creo 8.0 二次开发、企业级标准零部件库 ResLib 的设计与 License 体系</li>
|
||||
<li><strong>数字化孪生</strong>:three.js 可视化、MQTT 数据链路(EMQX)、数字孪生平台落地</li>
|
||||
<li><strong>工程与运维</strong>:Python、1Panel、OpenResty 反代与多站点部署实践</li>
|
||||
</ul>
|
||||
<p>后续内容陆续更新。</p>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container footer-inner">
|
||||
<span>Copyright © 2026 Easy Data Collector. All rights reserved.</span>
|
||||
<span><a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">苏ICP备2026056863号</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/static/js/nav.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>江北的渔夫的空间</title>
|
||||
<meta name="description" content="江北的渔夫的空间 —— 工业软件、标准件库与数字化实践分享">
|
||||
<meta name="keywords" content="江北的渔夫的空间, Easy Data Collector, ResLib, 资源中心管理器, Creo, 标准零部件库, 数字孪生">
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="icon" href="/static/img/logo.svg" type="image/svg+xml">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="brand" href="/">
|
||||
<img src="/static/img/logo.svg" alt="Easy Data Collector">
|
||||
<span class="brand-name">Easy Data Collector</span>
|
||||
</a>
|
||||
<nav class="main-nav" id="mainNav">
|
||||
<a href="/">博客</a>
|
||||
<a href="/reslib/">ResLib</a>
|
||||
<a href="/reslib/apply">申请 License</a>
|
||||
<a href="/reslib/status">查询 / 下载</a>
|
||||
<a href="/reslib/package">资源包获取</a>
|
||||
<a href="https://ec.sincos.cc">Engineer Craft</a>
|
||||
<a href="https://dt.sincos.cc">Digital Twin</a>
|
||||
<a href="https://neural.sincos.cc">Neural Research</a>
|
||||
<a href="https://git.sincos.cc">Gitea Project</a>
|
||||
</nav>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">博客</h2>
|
||||
<p class="section-desc">工业软件、标准件库与数字化实践记录。</p>
|
||||
<div class="post-list">
|
||||
|
||||
<a class="post-card" href="/blog/2026-08-13-welcome/">
|
||||
<div class="post-meta"><span class="post-date">2026年08月13日</span><span class="tag">公告</span><span class="tag">ResLib</span><span class="tag">数字孪生</span></div>
|
||||
<h3 class="post-title">博客开张</h3>
|
||||
<p class="post-excerpt">博客开张 用统一风格搭建的聚合博客正式上线,部署在 sincos.cc。 本站主要记录: 工业软件:Creo 8.0 二次开发、企业级标准零部件库 ResLib 的设计与 License 体系 数字化孪生:three.js 可视化、MQTT…</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container footer-inner">
|
||||
<span>Copyright © 2026 Easy Data Collector. All rights reserved.</span>
|
||||
<span><a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">苏ICP备2026056863号</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/static/js/nav.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,266 @@
|
||||
:root {
|
||||
--blue: #005eb8;
|
||||
--blue-dark: #00427f;
|
||||
--blue-light: #0a7bd8;
|
||||
--ink: #1c2b3a;
|
||||
--ink-light: #3d5a75;
|
||||
--bg-soft: #f4f8fd;
|
||||
--line: #e3ecf5;
|
||||
--danger: #c0392b;
|
||||
--ok: #1e8449;
|
||||
--radius: 10px;
|
||||
}
|
||||
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
font-family: "Segoe UI", "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
color: var(--ink);
|
||||
background: #fff;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.container { width: 100%; max-width: 1320px; margin: 0 auto; padding: 0 32px; }
|
||||
.container.narrow { max-width: 720px; margin: 0 auto; }
|
||||
|
||||
a { color: var(--blue); text-decoration: none; }
|
||||
a:hover { color: var(--blue-dark); }
|
||||
|
||||
/* Header */
|
||||
.site-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: rgba(255, 255, 255, 0.97);
|
||||
border-bottom: 1px solid var(--line);
|
||||
z-index: 100;
|
||||
}
|
||||
.header-inner {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
min-height: 60px; padding: 10px 0; gap: 12px;
|
||||
position: relative;
|
||||
}
|
||||
.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; color: var(--ink); flex-shrink: 0; }
|
||||
.brand img { width: 26px; height: 26px; }
|
||||
.brand-name { color: var(--blue); font-size: 1.1rem; white-space: nowrap; }
|
||||
|
||||
.nav-toggle {
|
||||
display: none; margin-left: auto;
|
||||
background: none; border: 1px solid var(--line); border-radius: 6px;
|
||||
font-size: 1.3rem; line-height: 1; color: var(--blue);
|
||||
padding: 6px 12px; cursor: pointer;
|
||||
}
|
||||
|
||||
.main-nav { display: flex; gap: 20px; align-items: center; flex-wrap: nowrap; }
|
||||
.main-nav a { color: var(--ink-light); font-size: 0.93rem; font-weight: 500; white-space: nowrap; }
|
||||
.main-nav a:hover, .main-nav a.active { color: var(--blue); }
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
.main-nav { gap: 14px; }
|
||||
.main-nav a { font-size: 0.88rem; }
|
||||
}
|
||||
|
||||
@media (max-width: 1080px) {
|
||||
.nav-toggle { display: block; }
|
||||
.main-nav {
|
||||
display: none; position: absolute; top: 100%; left: 0; right: 0;
|
||||
background: #fff; border-bottom: 1px solid var(--line);
|
||||
flex-direction: column; align-items: stretch; gap: 0;
|
||||
padding: 8px 0; box-shadow: 0 12px 24px rgba(0, 30, 60, 0.10);
|
||||
}
|
||||
.main-nav.open { display: flex; }
|
||||
.main-nav a { padding: 12px 32px; font-size: 0.95rem; }
|
||||
.main-nav a:hover { background: var(--bg-soft); }
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.btn {
|
||||
display: inline-block; padding: 11px 24px; border-radius: 6px;
|
||||
font-weight: 600; font-size: 0.95rem; border: 1px solid transparent;
|
||||
cursor: pointer; font-family: inherit; text-align: center;
|
||||
transition: background 0.15s ease, color 0.15s ease;
|
||||
}
|
||||
.btn-primary { background: var(--blue); color: #fff; }
|
||||
.btn-primary:hover { background: var(--blue-dark); color: #fff; }
|
||||
.btn-ghost { background: transparent; color: var(--blue); border-color: var(--blue); }
|
||||
.btn-ghost:hover { background: #e8f2ff; }
|
||||
.btn-danger { background: #fff; color: var(--danger); border-color: var(--danger); }
|
||||
.btn-danger:hover { background: #fdf0ee; }
|
||||
.btn-block { width: 100%; }
|
||||
.btn-sm { padding: 7px 14px; font-size: 0.85rem; }
|
||||
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }
|
||||
|
||||
/* Hero */
|
||||
.hero {
|
||||
background: linear-gradient(135deg, #003766 0%, #005eb8 55%, #0a7bd8 100%);
|
||||
color: #fff; padding: 76px 0 84px; position: relative; overflow: hidden;
|
||||
}
|
||||
.hero { max-width: none; }
|
||||
.hero::before, .hero::after {
|
||||
content: ""; position: absolute; border-radius: 50%;
|
||||
background: radial-gradient(circle, rgba(255,255,255,0.12) 0%, transparent 70%);
|
||||
}
|
||||
.hero::before { width: 460px; height: 460px; right: -130px; top: -150px; }
|
||||
.hero::after { width: 320px; height: 320px; left: -100px; bottom: -140px; }
|
||||
.hero .container { position: relative; }
|
||||
.hero h1 { font-size: 2.4rem; font-weight: 700; line-height: 1.2; }
|
||||
.hero-eyebrow {
|
||||
font-size: 0.9rem; letter-spacing: 0.18em;
|
||||
color: #bcd9f5; margin-bottom: 18px;
|
||||
}
|
||||
.hero-sub { max-width: 640px; margin: 16px 0 28px; color: #e8f2ff; font-size: 1.05rem; }
|
||||
.hero-actions { display: flex; gap: 12px; flex-wrap: wrap; }
|
||||
|
||||
/* 欧拉恒等式装饰 */
|
||||
.hero-euler {
|
||||
position: absolute; right: 18%; top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-family: Georgia, "Times New Roman", serif;
|
||||
font-style: italic;
|
||||
font-size: clamp(1.6rem, 4.5vw, 4rem);
|
||||
color: rgba(255, 255, 255, 0.14);
|
||||
pointer-events: none; user-select: none;
|
||||
white-space: nowrap; letter-spacing: 0.02em;
|
||||
}
|
||||
.hero-euler sup { font-size: 0.6em; }
|
||||
.btn-light { background: #fff; color: var(--blue); }
|
||||
.btn-light:hover { background: #e8f2ff; color: var(--blue-dark); }
|
||||
.btn-outline-light { background: transparent; color: #fff; border-color: rgba(255,255,255,0.7); }
|
||||
.btn-outline-light:hover { background: rgba(255,255,255,0.12); }
|
||||
|
||||
/* Sections & cards */
|
||||
.section { padding: 64px 0; }
|
||||
.section-alt { background: var(--bg-soft); }
|
||||
.section-title {
|
||||
font-size: 1.55rem; color: var(--blue-dark);
|
||||
border-left: 4px solid var(--blue); padding-left: 14px; margin-bottom: 10px;
|
||||
}
|
||||
.section-desc { color: var(--ink-light); margin-bottom: 26px; }
|
||||
|
||||
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px; margin-top: 26px; }
|
||||
.card {
|
||||
background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
|
||||
padding: 26px 24px; transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
.card:hover { transform: translateY(-3px); box-shadow: 0 10px 28px rgba(0,94,184,0.10); }
|
||||
.card .icon { font-size: 1.7rem; color: var(--blue); margin-bottom: 12px; }
|
||||
.card h3 { font-size: 1.05rem; color: var(--blue-dark); margin-bottom: 8px; }
|
||||
.card p { font-size: 0.93rem; color: var(--ink-light); }
|
||||
|
||||
/* Forms */
|
||||
.form-card {
|
||||
background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
|
||||
padding: 30px 28px; margin-top: 26px;
|
||||
}
|
||||
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
|
||||
.form-group { margin-bottom: 16px; }
|
||||
.form-group label { display: block; font-size: 0.88rem; font-weight: 600; margin-bottom: 6px; }
|
||||
.form-group input, .form-group select, .form-group textarea {
|
||||
width: 100%; padding: 10px 13px; border: 1px solid #cfdcea; border-radius: 6px;
|
||||
font-size: 0.93rem; font-family: inherit; background: #fbfdff; color: var(--ink);
|
||||
}
|
||||
.form-group input:focus, .form-group select:focus, .form-group textarea:focus {
|
||||
outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(0,94,184,0.12);
|
||||
}
|
||||
.form-hint { font-size: 0.82rem; color: var(--ink-light); margin-top: 4px; }
|
||||
.form-tip { margin-top: 14px; font-size: 0.88rem; text-align: center; }
|
||||
|
||||
/* Result / alerts */
|
||||
.alert { padding: 12px 16px; border-radius: 6px; font-size: 0.92rem; margin-top: 14px; display: none; }
|
||||
.alert.show { display: block; }
|
||||
.alert-ok { background: #e9f7ef; color: var(--ok); border: 1px solid #b8e6c8; }
|
||||
.alert-err { background: #fdf0ee; color: var(--danger); border: 1px solid #f2c4be; }
|
||||
|
||||
.badge { display: inline-block; padding: 2px 12px; border-radius: 20px; font-size: 0.8rem; font-weight: 600; }
|
||||
.badge-pending { background: #fef3dc; color: #9a6700; }
|
||||
.badge-approved { background: #e9f7ef; color: var(--ok); }
|
||||
.badge-denied { background: #fdf0ee; color: var(--danger); }
|
||||
|
||||
/* Admin table */
|
||||
.toolbar { display: flex; justify-content: space-between; align-items: center; margin: 24px 0 14px; flex-wrap: wrap; gap: 10px; }
|
||||
.table-wrap { overflow-x: auto; }
|
||||
table.admin { width: 100%; border-collapse: collapse; background: #fff; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; min-width: 720px; }
|
||||
table.admin th, table.admin td { padding: 11px 14px; text-align: left; font-size: 0.9rem; border-bottom: 1px solid var(--line); }
|
||||
table.admin th { background: var(--bg-soft); color: var(--blue-dark); font-weight: 600; white-space: nowrap; }
|
||||
table.admin tr:hover td { background: #f7fbff; }
|
||||
table.admin .actions { white-space: nowrap; }
|
||||
|
||||
/* Footer */
|
||||
.site-footer { background: var(--blue-dark); color: #d6e6f7; padding: 36px 0 24px; }
|
||||
.footer-inner { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; font-size: 0.86rem; }
|
||||
.site-footer a { color: #a9c6e3; }
|
||||
.site-footer a:hover { color: #fff; }
|
||||
|
||||
.mono { font-family: Consolas, monospace; letter-spacing: 0.04em; }
|
||||
|
||||
/* Blog */
|
||||
.breadcrumb { font-size: 0.85rem; color: var(--ink-light); margin-bottom: 14px; }
|
||||
.breadcrumb a { color: var(--ink-light); }
|
||||
.breadcrumb a:hover { color: var(--blue); }
|
||||
|
||||
.post-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 18px; margin-top: 26px; }
|
||||
.post-card {
|
||||
display: block; background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
|
||||
padding: 22px 24px; transition: transform 0.15s ease, box-shadow 0.15s ease; color: var(--ink);
|
||||
}
|
||||
.post-card:hover { transform: translateY(-3px); box-shadow: 0 10px 28px rgba(0, 94, 184, 0.10); color: var(--ink); }
|
||||
.post-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
|
||||
.post-date { font-size: 0.8rem; color: var(--ink-light); }
|
||||
.post-title { font-size: 1.08rem; color: var(--blue-dark); margin-bottom: 6px; }
|
||||
.post-excerpt { font-size: 0.9rem; color: var(--ink-light); line-height: 1.55; }
|
||||
|
||||
.tag {
|
||||
display: inline-block; font-size: 0.74rem; color: var(--blue);
|
||||
background: #e8f2ff; border-radius: 20px; padding: 1px 10px;
|
||||
}
|
||||
|
||||
/* Article */
|
||||
.article { line-height: 1.8; font-size: 0.98rem; color: var(--ink); margin-top: 20px; }
|
||||
.article h1, .article h2, .article h3, .article h4 {
|
||||
color: var(--blue-dark); margin: 1.6em 0 0.6em; line-height: 1.4;
|
||||
}
|
||||
.article h1 { font-size: 1.6rem; border-bottom: 1px solid var(--line); padding-bottom: 0.3em; }
|
||||
.article h2 { font-size: 1.3rem; }
|
||||
.article h3 { font-size: 1.1rem; }
|
||||
.article p { margin: 0.8em 0; }
|
||||
.article ul, .article ol { padding-left: 1.5em; margin: 0.8em 0; }
|
||||
.article li { margin: 0.3em 0; }
|
||||
.article code {
|
||||
background: #eef4fb; color: #00518f; border-radius: 4px;
|
||||
padding: 1px 6px; font-family: Consolas, monospace; font-size: 0.9em;
|
||||
}
|
||||
.article pre {
|
||||
background: #0d2b4a; color: #d8ecff; border-radius: 8px;
|
||||
padding: 16px 18px; overflow-x: auto; margin: 1em 0;
|
||||
}
|
||||
.article pre code { background: none; color: inherit; padding: 0; }
|
||||
.article blockquote {
|
||||
border-left: 4px solid var(--blue); background: var(--bg-soft);
|
||||
padding: 10px 16px; margin: 1em 0; color: var(--ink-light); border-radius: 0 6px 6px 0;
|
||||
}
|
||||
.article table { width: 100%; border-collapse: collapse; margin: 1em 0; font-size: 0.92rem; }
|
||||
.article th, .article td { border: 1px solid var(--line); padding: 8px 12px; text-align: left; }
|
||||
.article th { background: var(--bg-soft); color: var(--blue-dark); }
|
||||
.article img { max-width: 100%; border-radius: 8px; }
|
||||
.article a { text-decoration: underline; }
|
||||
|
||||
/* Card as link */
|
||||
.card-link { display: block; color: var(--ink); }
|
||||
.card-link:hover { color: var(--ink); }
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.post-list { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.main-nav { gap: 12px 16px; }
|
||||
.main-nav a { font-size: 0.88rem; }
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.form-row { grid-template-columns: 1fr; }
|
||||
.hero h1 { font-size: 1.8rem; }
|
||||
.hero { padding: 56px 0 64px; }
|
||||
.section { padding: 48px 0; }
|
||||
.container { padding: 0 18px; }
|
||||
.hero-actions .btn { width: 100%; }
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>江北的渔夫的空间</title>
|
||||
<meta name="description" content="江北的渔夫的空间 —— 工业软件、标准件库与数字化实践分享">
|
||||
<meta name="keywords" content="江北的渔夫的空间, Easy Data Collector, ResLib, 资源中心管理器, Creo, 标准零部件库, 数字孪生">
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="icon" href="/static/img/logo.svg" type="image/svg+xml">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="brand" href="/">
|
||||
<img src="/static/img/logo.svg" alt="Easy Data Collector">
|
||||
<span class="brand-name">Easy Data Collector</span>
|
||||
</a>
|
||||
<nav class="main-nav" id="mainNav">
|
||||
<a href="/" class=active>博客</a>
|
||||
<a href="/reslib/">ResLib</a>
|
||||
<a href="/reslib/apply">申请 License</a>
|
||||
<a href="/reslib/status">查询 / 下载</a>
|
||||
<a href="/reslib/package">资源包获取</a>
|
||||
<a href="https://ec.sincos.cc">Engineer Craft</a>
|
||||
<a href="https://dt.sincos.cc">Digital Twin</a>
|
||||
<a href="https://neural.sincos.cc">Neural Research</a>
|
||||
<a href="https://git.sincos.cc">Gitea Project</a>
|
||||
</nav>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="hero">
|
||||
<div class="hero-euler" aria-hidden="true">e<sup>iπ</sup> + 1 = 0</div>
|
||||
<div class="container">
|
||||
<p class="hero-eyebrow">INDUSTRIAL SOFTWARE · STANDARD PARTS · DIGITAL PRACTICE</p>
|
||||
<h1>从数学出发</h1>
|
||||
<p class="hero-sub">记录工程与代码 —— 工业软件 · 标准件库 · 数字化实践,Easy Data Collector 旗下各平台的技术博客。</p>
|
||||
<div class="hero-actions">
|
||||
<a href="/blog/" class="btn btn-light">全部文章</a>
|
||||
<a href="/reslib/" class="btn btn-outline-light">ResLib 产品</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">平台</h2>
|
||||
<div class="grid">
|
||||
<a class="card card-link" href="/reslib/">
|
||||
<div class="icon">▤</div><h3>ResLib</h3><p>资源中心管理器 —— Creo 7.0+ 企业级标准零部件管理库,含 LIC 授权体系与在线申请。</p>
|
||||
</a>
|
||||
<a class="card card-link" href="https://ec.sincos.cc">
|
||||
<div class="icon">⚙</div><h3>Engineer Craft</h3><p>工程实践与工艺设计平台。</p>
|
||||
</a>
|
||||
<a class="card card-link" href="https://dt.sincos.cc">
|
||||
<div class="icon">◉</div><h3>Digital Twin</h3><p>three.js 三维可视化 · MQTT 实时数据 · 数字孪生平台。</p>
|
||||
</a>
|
||||
<a class="card card-link" href="https://neural.sincos.cc">
|
||||
<div class="icon">◈</div><h3>Neural Research</h3><p>神经网络与算法研究。</p>
|
||||
</a>
|
||||
<a class="card card-link" href="https://git.sincos.cc">
|
||||
<div class="icon">⌥</div><h3>Gitea Project</h3><p>代码托管与版本管理。</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section section-alt">
|
||||
<div class="container">
|
||||
<h2 class="section-title">最新文章</h2>
|
||||
<div class="post-list">
|
||||
|
||||
<a class="post-card" href="/blog/2026-08-13-welcome/">
|
||||
<div class="post-meta"><span class="post-date">2026年08月13日</span></div>
|
||||
<h3 class="post-title">博客开张</h3>
|
||||
<p class="post-excerpt">博客开张 用统一风格搭建的聚合博客正式上线,部署在 sincos.cc。 本站主要记录: 工业软件:Creo 8.0 二次开发、企业级标准零部件库 ResLib 的设计与 Lice…</p>
|
||||
</a>
|
||||
</div>
|
||||
<div style="text-align:center; margin-top: 30px;">
|
||||
<a href="/blog/" class="btn btn-primary">查看全部文章</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container footer-inner">
|
||||
<span>Copyright © 2026 Easy Data Collector. All rights reserved.</span>
|
||||
<span><a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">苏ICP备2026056863号</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/static/js/nav.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="7" fill="#005EB8"/>
|
||||
<rect x="6" y="7" width="8" height="8" rx="2" fill="#fff"/>
|
||||
<rect x="18" y="7" width="8" height="8" rx="2" fill="#7cc0ff"/>
|
||||
<rect x="6" y="17" width="8" height="8" rx="2" fill="#7cc0ff"/>
|
||||
<rect x="18" y="17" width="8" height="8" rx="2" fill="#fff"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 381 B |
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>江北的渔夫的空间 | Easy Data Collector</title>
|
||||
<meta name="description" content="江北的渔夫的空间 —— 工业软件、标准件库与数字化实践分享。Easy Data Collector 旗下 ResLib 资源中心管理器:Creo 7.0+ 企业级标准零部件管理库。">
|
||||
<meta name="keywords" content="江北的渔夫的空间, Easy Data Collector, ResLib, 资源中心管理器, Creo, 标准零部件库, License">
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="icon" href="/static/img/logo.svg" type="image/svg+xml">
|
||||
<script src="/static/js/nav.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="brand" href="/reslib/">
|
||||
<img src="/static/img/logo.svg" alt="Easy Data Collector">
|
||||
<span class="brand-name">Easy Data Collector</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="/blog/">博客</a>
|
||||
<a href="/reslib/" class="active">ResLib</a>
|
||||
<a href="/reslib/apply">申请 License</a>
|
||||
<a href="/reslib/status">查询 / 下载</a>
|
||||
<a href="/reslib/package">资源包获取</a>
|
||||
<a href="https://ec.sincos.cc">Engineer Craft</a>
|
||||
<a href="https://dt.sincos.cc">Digital Twin</a>
|
||||
<a href="https://neural.sincos.cc">Neural Research</a>
|
||||
<a href="https://git.sincos.cc">Gitea Project</a>
|
||||
</nav>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="hero">
|
||||
<div class="container">
|
||||
<h1>资源中心管理器 ResLib</h1>
|
||||
<p class="hero-sub">面向 Creo 7.0+ 的企业级标准零部件管理库 —— 标准件浏览、3D 预览、搜索过滤、快速装配,配套自研 LIC 授权体系。</p>
|
||||
<div class="hero-actions">
|
||||
<a href="/reslib/apply" class="btn btn-light">申请 License</a>
|
||||
<a href="/reslib/status" class="btn btn-outline-light">查询申请状态</a>
|
||||
<a href="/reslib/package" class="btn btn-outline-light">资源包获取</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">核心功能</h2>
|
||||
<div class="grid">
|
||||
<div class="card"><div class="icon">▤</div><h3>标准件库浏览</h3><p>TreeView 目录树 + 零件列表,直接扫描目录中的 .prt / .asm 文件,去重保留最高版本。</p></div>
|
||||
<div class="card"><div class="icon">◉</div><h3>3D 实时预览</h3><p>OpenGL 三角面片渲染,三点光源,鼠标旋转 / 缩放,装配体递归解析。</p></div>
|
||||
<div class="card"><div class="icon">⌕</div><h3>全局搜索过滤</h3><p>递归全库匹配文件名,支持按名称快速定位标准件。</p></div>
|
||||
<div class="card"><div class="icon">⇱</div><h3>快速装配</h3><p>选中零件一键插入装配,或进入参数定位模式(X/Y/Z/RX/RY/RZ)精确装配。</p></div>
|
||||
<div class="card"><div class="icon">☆</div><h3>收藏与最近使用</h3><p>favorites / recent 记录,MRU 去重,常用件一键直达。</p></div>
|
||||
<div class="card"><div class="icon">⛨</div><h3>LIC 授权体系</h3><p>MAC 地址绑定授权,未授权时装配功能隐藏,保障企业版权。</p></div>
|
||||
<div class="card"><div class="icon">✎</div><h3>版本与功能定制</h3><p>支持按企业需求定制产品版本与扩展功能,贴合实际业务流程开发。</p></div>
|
||||
<div class="card"><div class="icon">☁</div><h3>私有云部署</h3><p>企业私有云部署与标准化同步服务,标准件库统一管理、多端实时同步。</p></div>
|
||||
<div class="card"><div class="icon">◍</div><h3>标准化降本</h3><p>减少 SKU 与同类物料,提升零部件借用率与标准化统一程度,有效降低成本。</p></div>
|
||||
<div class="card"><div class="icon">◈</div><h3>Inventor 服务</h3><p>提供 Autodesk Inventor 版本类似服务功能,多 CAD 平台标准件管理方案。</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">资源包内容</h2>
|
||||
<p class="section-desc">资源包随 License 发放,内置常用标准件库,覆盖以下品类:</p>
|
||||
<div class="grid">
|
||||
<div class="card"><div class="icon">▣</div><h3>标准化配件</h3><p>通用标准化零部件库,覆盖各行业通用件,开箱即用。</p></div>
|
||||
<div class="card"><div class="icon">❖</div><h3>BPE 卫生级配件</h3><p>符合 BPE 规范的卫生级管件、阀门与连接件,适用于生物制药与洁净工艺。</p></div>
|
||||
<div class="card"><div class="icon">✚</div><h3>食品 · 医药 · 包装配件</h3><p>食品、医药与包装工程常用配件库,贴合产线设计选型需求。</p></div>
|
||||
<div class="card"><div class="icon">⏏</div><h3>气动系统配件</h3><p>气缸、阀岛、接头等气动系统常用件,助力自动化产线快速搭建。</p></div>
|
||||
</div>
|
||||
<div style="text-align:center; margin-top: 28px;">
|
||||
<a href="/reslib/package" class="btn btn-primary">获取资源包</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section section-alt">
|
||||
<div class="container">
|
||||
<h2 class="section-title">版本与环境</h2>
|
||||
<div class="grid">
|
||||
<div class="card"><h3>适配版本</h3><p>Creo Parametric 7.0 ~ 10.0(64 位),Pro/TOOLKIT DLL 插件。</p></div>
|
||||
<div class="card"><h3>系统要求</h3><p>Windows 10 / 11 64 位,Visual C++ 2022 运行库。</p></div>
|
||||
<div class="card"><h3>部署形态</h3><p>本地部署:DLL + protk.dat + config\lic\res_center.lic,configen.exe 一键配置。</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="container narrow">
|
||||
<h2 class="section-title">License 申请流程</h2>
|
||||
<p class="section-desc">三步完成授权:</p>
|
||||
<div class="grid">
|
||||
<div class="card"><h3>1. 提交申请</h3><p>填写公司、联系人与机器 MAC 地址,提交后获得申请编号。</p></div>
|
||||
<div class="card"><h3>2. 人工审批</h3><p>我们核对信息后确认授权,通过后自动生成授权文件。</p></div>
|
||||
<div class="card"><h3>3. 下载安装</h3><p>凭申请编号查询状态并下载 <span class="mono">res_center.lic</span>,放入 config\lic\ 目录。</p></div>
|
||||
</div>
|
||||
<div style="text-align:center; margin-top: 28px;">
|
||||
<a href="/reslib/apply" class="btn btn-primary">开始申请</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container footer-inner">
|
||||
<span>Copyright © 2026 Easy Data Collector. All rights reserved.</span>
|
||||
<span><a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">苏ICP备2026056863号</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,16 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
var toggle = document.getElementById("navToggle");
|
||||
var nav = document.getElementById("mainNav");
|
||||
if (!toggle || !nav) return;
|
||||
toggle.addEventListener("click", function () {
|
||||
nav.classList.toggle("open");
|
||||
});
|
||||
document.addEventListener("click", function (e) {
|
||||
if (!nav.contains(e.target) && !toggle.contains(e.target)) {
|
||||
nav.classList.remove("open");
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>资源包获取 - 江北的渔夫的空间</title>
|
||||
<meta name="description" content="ResLib 资源包获取:仅对 License 审核通过的用户提供,凭申请编号验证后下载资源包。">
|
||||
<meta name="keywords" content="江北的渔夫的空间, ResLib, 资源包, License, 下载">
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="icon" href="/static/img/logo.svg" type="image/svg+xml">
|
||||
<script src="/static/js/nav.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="brand" href="/reslib/">
|
||||
<img src="/static/img/logo.svg" alt="Easy Data Collector">
|
||||
<span class="brand-name">Easy Data Collector</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="/blog/">博客</a>
|
||||
<a href="/reslib/">ResLib</a>
|
||||
<a href="/reslib/apply">申请 License</a>
|
||||
<a href="/reslib/status">查询 / 下载</a>
|
||||
<a href="/reslib/package" class="active">资源包获取</a>
|
||||
<a href="https://ec.sincos.cc">Engineer Craft</a>
|
||||
<a href="https://dt.sincos.cc">Digital Twin</a>
|
||||
<a href="https://neural.sincos.cc">Neural Research</a>
|
||||
<a href="https://git.sincos.cc">Gitea Project</a>
|
||||
</nav>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="section">
|
||||
<div class="container narrow">
|
||||
<h2 class="section-title">资源包获取</h2>
|
||||
<p class="section-desc">资源包(部署文件、标准件库样例、说明文档等)<b>仅对 License 审核通过的用户提供</b>,请凭申请编号验证身份。内含标准化配件、BPE 卫生级配件、食品 / 医药 / 包装工程常用配件与气动系统配件等标准件库。</p>
|
||||
|
||||
<div class="form-card">
|
||||
<div class="form-group">
|
||||
<label for="rid">申请编号</label>
|
||||
<input type="text" id="rid" class="mono" placeholder="如:20260813-201500-A1B2C3" autocomplete="off">
|
||||
</div>
|
||||
<button type="button" id="verify" class="btn btn-primary btn-block">验证并获取</button>
|
||||
<div id="result"></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container footer-inner">
|
||||
<span>Copyright © 2026 Easy Data Collector. All rights reserved.</span>
|
||||
<span><a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">苏ICP备2026056863号</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var btn = document.getElementById("verify");
|
||||
var result = document.getElementById("result");
|
||||
|
||||
btn.addEventListener("click", async function () {
|
||||
var rid = document.getElementById("rid").value.trim();
|
||||
if (!rid) { result.innerHTML = '<div class="alert show alert-err">请输入申请编号</div>'; return; }
|
||||
btn.disabled = true;
|
||||
btn.textContent = "验证中…";
|
||||
try {
|
||||
var resp = await fetch("/api/package/" + encodeURIComponent(rid));
|
||||
var data = await resp.json();
|
||||
if (resp.ok) {
|
||||
var html =
|
||||
'<div class="alert show alert-ok">' +
|
||||
"<b>身份验证通过</b>(申请编号 <span class='mono'>" + rid + "</span>)<br><br>" +
|
||||
"<b>可用资源包:</b><br>";
|
||||
data.files.forEach(function (f) {
|
||||
html += "<div style='margin:10px 0;'>📦 <span class='mono'>" + f + "</span><br>" +
|
||||
"<a class='btn btn-primary btn-sm' style='margin-top:6px;' href='/api/package/download/" +
|
||||
encodeURIComponent(rid) + "/" + encodeURIComponent(f) + "' download>下载</a></div>";
|
||||
});
|
||||
html += "</div>";
|
||||
result.innerHTML = html;
|
||||
} else {
|
||||
result.innerHTML = '<div class="alert show alert-err">' + (data.detail || "验证失败") + "</div>";
|
||||
}
|
||||
} catch (e) {
|
||||
result.innerHTML = '<div class="alert show alert-err">网络错误:' + e.message + "</div>";
|
||||
}
|
||||
btn.disabled = false;
|
||||
btn.textContent = "验证并获取";
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,109 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>查询 / 下载 License - ResLib</title>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="icon" href="/static/img/logo.svg" type="image/svg+xml">
|
||||
<script src="/static/js/nav.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="brand" href="/reslib/">
|
||||
<img src="/static/img/logo.svg" alt="ResLib">
|
||||
<span class="brand-name">ResLib</span>
|
||||
</a>
|
||||
<nav class="main-nav">
|
||||
<a href="/blog/">博客</a>
|
||||
<a href="/reslib/">ResLib</a>
|
||||
<a href="/reslib/apply">申请 License</a>
|
||||
<a href="/reslib/status" class="active">查询 / 下载</a>
|
||||
<a href="/reslib/package">资源包获取</a>
|
||||
<a href="https://ec.sincos.cc">Engineer Craft</a>
|
||||
<a href="https://dt.sincos.cc">Digital Twin</a>
|
||||
<a href="https://neural.sincos.cc">Neural Research</a>
|
||||
<a href="https://git.sincos.cc">Gitea Project</a>
|
||||
</nav>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
<button class="nav-toggle" id="navToggle" aria-label="菜单">☰</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="section">
|
||||
<div class="container narrow">
|
||||
<h2 class="section-title">查询申请状态</h2>
|
||||
<p class="section-desc">输入申请时获得的申请编号。</p>
|
||||
|
||||
<div class="form-card">
|
||||
<div class="form-group">
|
||||
<label for="rid">申请编号</label>
|
||||
<input type="text" id="rid" class="mono" placeholder="如:20260813-201500-A1B2C3" autocomplete="off">
|
||||
</div>
|
||||
<button type="button" id="query" class="btn btn-primary btn-block">查询</button>
|
||||
<div id="result"></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container footer-inner">
|
||||
<span>Copyright © 2026 SinCos. All rights reserved.</span>
|
||||
<span><a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">苏ICP备2026056863号</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var btn = document.getElementById("query");
|
||||
var result = document.getElementById("result");
|
||||
|
||||
function statusBadge(s) {
|
||||
if (s === "approved") return '<span class="badge badge-approved">已批准</span>';
|
||||
if (s === "denied") return '<span class="badge badge-denied">已拒绝</span>';
|
||||
return '<span class="badge badge-pending">审核中</span>';
|
||||
}
|
||||
|
||||
function show(html) {
|
||||
result.innerHTML = html;
|
||||
}
|
||||
|
||||
btn.addEventListener("click", async function () {
|
||||
var rid = document.getElementById("rid").value.trim();
|
||||
if (!rid) { show('<div class="alert show alert-err">请输入申请编号</div>'); return; }
|
||||
btn.disabled = true;
|
||||
btn.textContent = "查询中…";
|
||||
try {
|
||||
var resp = await fetch("/api/status/" + encodeURIComponent(rid));
|
||||
var data = await resp.json();
|
||||
if (resp.ok) {
|
||||
var html =
|
||||
'<div class="alert show alert-ok">' +
|
||||
"<b>申请编号:</b><span class='mono'>" + data.id + "</span><br>" +
|
||||
"<b>提交时间:</b>" + data.created + "<br>" +
|
||||
"<b>当前状态:</b>" + statusBadge(data.status);
|
||||
if (data.status === "approved") {
|
||||
html += "<br><br><a class='btn btn-primary' href='/api/license/" + encodeURIComponent(data.id) +
|
||||
"' download>下载 res_center.lic</a>";
|
||||
} else if (data.status === "denied" && data.reason) {
|
||||
html += "<br><b>原因:</b>" + data.reason;
|
||||
} else {
|
||||
html += "<br>请耐心等待审核,稍后再来查询。";
|
||||
}
|
||||
html += "</div>";
|
||||
show(html);
|
||||
} else {
|
||||
show('<div class="alert show alert-err">' + (data.detail || "查询失败") + "</div>");
|
||||
}
|
||||
} catch (e) {
|
||||
show('<div class="alert show alert-err">网络错误:' + e.message + "</div>");
|
||||
}
|
||||
btn.disabled = false;
|
||||
btn.textContent = "查询";
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user