chore: reorganize project into monorepo

This commit is contained in:
2026-03-28 10:40:22 +08:00
parent 60367a5f51
commit 1455d93246
201 changed files with 30081 additions and 93 deletions

View File

@@ -0,0 +1,143 @@
{% extends "admin/base.html" %}
{% block main_content %}
<section class="form-panel">
<div class="table-head">
<div>
<h2>站点资料</h2>
<div class="table-note">保存后首页、关于页、页脚和友链页中的本站信息会直接读取这里的配置。</div>
</div>
</div>
<form id="site-settings-form" class="form-grid">
<div class="field">
<label>站点名称</label>
<input name="site_name" value="{{ form.site_name }}">
</div>
<div class="field">
<label>短名称</label>
<input name="site_short_name" value="{{ form.site_short_name }}">
</div>
<div class="field">
<label>站点链接</label>
<input name="site_url" value="{{ form.site_url }}">
</div>
<div class="field field-wide">
<label>站点标题</label>
<input name="site_title" value="{{ form.site_title }}">
</div>
<div class="field field-wide">
<label>站点简介</label>
<textarea name="site_description">{{ form.site_description }}</textarea>
</div>
<div class="field">
<label>首页主标题</label>
<input name="hero_title" value="{{ form.hero_title }}">
</div>
<div class="field">
<label>首页副标题</label>
<input name="hero_subtitle" value="{{ form.hero_subtitle }}">
</div>
<div class="field">
<label>个人名称</label>
<input name="owner_name" value="{{ form.owner_name }}">
</div>
<div class="field">
<label>个人头衔</label>
<input name="owner_title" value="{{ form.owner_title }}">
</div>
<div class="field">
<label>头像 URL</label>
<input name="owner_avatar_url" value="{{ form.owner_avatar_url }}">
</div>
<div class="field">
<label>所在地</label>
<input name="location" value="{{ form.location }}">
</div>
<div class="field">
<label>GitHub</label>
<input name="social_github" value="{{ form.social_github }}">
</div>
<div class="field">
<label>Twitter / X</label>
<input name="social_twitter" value="{{ form.social_twitter }}">
</div>
<div class="field field-wide">
<label>Email / mailto</label>
<input name="social_email" value="{{ form.social_email }}">
</div>
<div class="field field-wide">
<label>个人简介</label>
<textarea name="owner_bio">{{ form.owner_bio }}</textarea>
</div>
<div class="field field-wide">
<label>技术栈(每行一个)</label>
<textarea name="tech_stack">{{ form.tech_stack }}</textarea>
</div>
<div class="field field-wide">
<div class="actions">
<button type="submit" class="btn btn-primary">保存设置</button>
</div>
<div class="field-hint" style="margin-top: 10px;">保存后可直接点击顶部“预览首页 / 预览关于页 / 预览友链页”确认前台展示。</div>
<div id="notice" class="notice"></div>
</div>
</form>
</section>
{% endblock %}
{% block page_scripts %}
<script>
const form = document.getElementById("site-settings-form");
const notice = document.getElementById("notice");
function showNotice(message, kind) {
notice.textContent = message;
notice.className = "notice show " + (kind === "success" ? "notice-success" : "notice-error");
}
form?.addEventListener("submit", async (event) => {
event.preventDefault();
const data = new FormData(form);
const payload = {
siteName: data.get("site_name"),
siteShortName: data.get("site_short_name"),
siteUrl: data.get("site_url"),
siteTitle: data.get("site_title"),
siteDescription: data.get("site_description"),
heroTitle: data.get("hero_title"),
heroSubtitle: data.get("hero_subtitle"),
ownerName: data.get("owner_name"),
ownerTitle: data.get("owner_title"),
ownerAvatarUrl: data.get("owner_avatar_url"),
location: data.get("location"),
socialGithub: data.get("social_github"),
socialTwitter: data.get("social_twitter"),
socialEmail: data.get("social_email"),
ownerBio: data.get("owner_bio"),
techStack: String(data.get("tech_stack") || "")
.split("\n")
.map((item) => item.trim())
.filter(Boolean)
};
try {
const response = await fetch("/api/site_settings", {
method: "PATCH",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(await response.text() || "save failed");
}
showNotice("站点信息已保存。", "success");
} catch (error) {
showNotice("保存失败:" + (error?.message || "unknown error"), "error");
}
});
</script>
{% endblock %}