feat(devops): 发版拆分为 client/site/server 三条独立流水线

将单一 CI/CD 流水线拆成三条互不影响的发布流水线,各有 tag 前缀、独立版本
序列与独立 CHANGELOG:

- client(client-v*):Flutter 全平台 + version.yaml 自更新清单
- site(site-v*):web/ Eleventy 营销站,不含 web 版 app
- server(server-v*):backend Go 服务 + 共享基建 nginx/systemd

新增 3 个 workflow(deploy-client/site/server.yml)替换 deploy.yml;CI 脚本
按 part 拆分为 compile-/release-/deploy-{client,site,server}.sh,抽出公共函数
lib-forgejo.sh;compile-{macos,android,ios,windows}.sh 改去 client-v 前缀;
manual.yml 按前缀路由回滚。

跨流水线解耦:version.yaml 归 client,后端每请求实时读取(不重启、不触发
server 流水线);官网下载页的版本徽章/下载链接/更新日志时间线运行时经
/api/v1/public/release 动态拉取(API 不可达回退构建时静态内容)。为此一次性
扩展后端 changelog 字段(version.go/public.go)与 download.njk 动态渲染。

CHANGELOG.md 重命名为 CHANGELOG-client.md,新增 CHANGELOG-site/server.md;
重写 /release 命令为 /release <part> [version];同步更新 CLAUDE.md 与部署文档。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-17 08:21:28 +08:00
parent eca62ba2c3
commit aa7099ba94
39 changed files with 998 additions and 534 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ const fs = require('fs');
const path = require('path');
module.exports = function() {
const raw = fs.readFileSync(path.join(__dirname, '../../CHANGELOG.md'), 'utf8');
const raw = fs.readFileSync(path.join(__dirname, '../../CHANGELOG-client.md'), 'utf8');
const lines = raw.split('\n');
const versions = [];
let current = null;
+3 -4
View File
@@ -72,7 +72,7 @@
<div class="docs-version">
<i data-lucide="tag" class="icon"></i>
<span class="docs-version-label">版本</span>
<span>v1.0.23</span>
<span>v1.0.54</span>
</div>
</div>
</div>
@@ -840,6 +840,7 @@
<img src="/assets/logo-full.svg" alt="岩美" />
<p>为酒行与酒店设计的库存、审核、财务一体化管理平台。</p>
<div class="footer-contact">
<div><a href="mailto:yammy2023@163.com">yammy2023@163.com</a></div>
</div>
@@ -872,14 +873,12 @@
<h5>公司</h5>
<ul>
<li><a href="/register/">注册门店</a></li>
<li><a href="/terms/">服务条款</a></li>
<li><a href="/privacy/">隐私政策</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<div>© 2026 岩美科技 · 保留所有权利</div>
<div>沪 ICP 备 2026000000 号 · 沪公网安备 31010000000000 号</div>
</div>
</div>
</footer>
+89 -66
View File
@@ -308,7 +308,7 @@
<div class="container ph-inner">
<div>
<div class="ph-eyebrow">
<span class="version-badge">v1.0.23</span>
<span class="version-badge">v1.0.54</span>
<span>下载岩美</span>
</div>
<h1 class="ph-title">随时随地,<br/>轻松管理酒库。</h1>
@@ -318,11 +318,11 @@
<div class="ph-meta">
<div class="ph-meta-item">
<div class="ph-meta-label">最新版本</div>
<div class="ph-meta-val version-badge">v1.0.23</div>
<div class="ph-meta-val version-badge">v1.0.54</div>
</div>
<div class="ph-meta-item">
<div class="ph-meta-label">发布日期</div>
<div class="ph-meta-val">2026-06-07</div>
<div class="ph-meta-val">2026-06-17</div>
</div>
<div class="ph-meta-item">
<div class="ph-meta-label">可用平台</div>
@@ -545,14 +545,14 @@
<section class="section">
<div class="container">
<h2 class="fs-3xl fw-6 text-brand-900 m-0 mb-6" style="letter-spacing: var(--tracking-cn-display);">版本更新日志</h2>
<p class="fs-md text-muted m-0">最近 3 个版本。</p>
<p class="fs-md text-muted m-0" id="changelog-count">最近 3 个版本。</p>
<div class="changelog">
<div class="changelog" id="changelog-list">
<div class="changelog-entry current">
<div class="changelog-meta">
<div class="changelog-version">v1.0.23</div>
<div class="changelog-date">2026-06-07</div>
<div class="changelog-version">v1.0.54</div>
<div class="changelog-date">2026-06-17</div>
<span class="changelog-tag">当前版本</span>
</div>
<div class="changelog-body">
@@ -561,12 +561,16 @@
<div class="changelog-cat">
<div class="changelog-cat-label">
<span class="dot dot-fix"></span>问题修复
<span class="dot dot-feature"></span>新功能
</div>
<ul>
<li>官网功能详情页(库存管理/审核流)导航栏现与主站完全一致,不再缺少「库存」「审核流」入口</li>
<li>只读账号自动隐藏所有写操作按钮(新增/编辑/删除/审核/提交/结清/导入等),顶栏显示「只读」标识,权限一目了然</li>
<li>左侧抽屉和系统设置页新增「退出登录」入口,窄屏也能方便退出</li>
<li>酒行信息新增「微信号」显示</li>
</ul>
</div>
@@ -579,47 +583,9 @@
</div>
<ul>
<li>官网功能详情页接入统一模板系统,导航/页脚/版权信息改一处自动同步全站</li>
<li>网络请求失败时自动重试(间隔递增),离线时提供带状态反馈的「重试」按钮</li>
</ul>
</div>
</div>
</div>
<div class="changelog-entry">
<div class="changelog-meta">
<div class="changelog-version">v1.0.22</div>
<div class="changelog-date">2026-06-07</div>
</div>
<div class="changelog-body">
<div class="changelog-cat">
<div class="changelog-cat-label">
<span class="dot dot-feature"></span>新功能
</div>
<ul>
<li>官网移动端适配:手机浏览器下导航折叠、首页各区块单列排版、features 详情页和页脚自适应窄屏</li>
</ul>
</div>
<div class="changelog-cat">
<div class="changelog-cat-label">
<span class="dot dot-improve"></span>改进
</div>
<ul>
<li>客户端移动端布局优化:入库/出库详情页商品明细改为卡片式竖排,操作按钮收纳至溢出菜单,窄屏不再横向溢出</li>
<li>信息架构整理:仓库管理移入基础数据,系统设置新增授权 Tab 和数据管理组,关于我们补充帮助文档/法律信息/系统信息入口</li>
<li>iOS 顶栏避开状态栏,菜单按钮不再被时间/信号遮挡</li>
</ul>
</div>
@@ -632,17 +598,9 @@
</div>
<ul>
<li>官网所有功能页死链修正(`/download.html` → `/download/``/docs.html` → `/docs/`</li>
<li>库存导入改用 Excel 中的「入库日期」作为入库时间(不再统一记为导入当天);相同数据重复导入时自动跳过,仅更新有变化的字段,避免重复与误覆盖</li>
<li>官网删除未实现功能的虚假宣传(红冲、调拨单、库存推送通知、过期预警等),文案与实际功能对齐</li>
<li>官网客服邮箱更新为真实邮箱,移除假冒客服电话,页脚清除无目标死链</li>
<li>导航新增「库存」「审核流」功能页入口,首页模块卡加「了解更多」链接</li>
<li>下载页接口失败时按钮改为禁用态并提示,不再无响应</li>
<li>首页 iOS 平台说明改为「TestFlight 内测中」,与下载页状态一致</li>
<li>修复 iOS 上顶栏被状态栏遮挡导致无法打开菜单/退出登录的问题</li>
</ul>
</div>
@@ -652,8 +610,8 @@
<div class="changelog-entry">
<div class="changelog-meta">
<div class="changelog-version">v1.0.21</div>
<div class="changelog-date">2026-06-07</div>
<div class="changelog-version">v1.0.53</div>
<div class="changelog-date">2026-06-15</div>
</div>
<div class="changelog-body">
@@ -662,12 +620,37 @@
<div class="changelog-cat">
<div class="changelog-cat-label">
<span class="dot dot-feature"></span>新功能
<span class="dot dot-fix"></span>问题修复
</div>
<ul>
<li>商品详情页添加照片时,手机端(Android/iOS)支持直接拍照或从相册选择</li>
<li>修复 Windows 上点击打印无反应的问题(GBK 编码改为直接调用系统 API,不再依赖第三方插件)</li>
</ul>
</div>
</div>
</div>
<div class="changelog-entry">
<div class="changelog-meta">
<div class="changelog-version">v1.0.52</div>
<div class="changelog-date">2026-06-15</div>
</div>
<div class="changelog-body">
<div class="changelog-cat">
<div class="changelog-cat-label">
<span class="dot dot-improve"></span>改进
</div>
<ul>
<li>热敏标签打印改用打印机内置中文点阵字体(TSS24.BF2/TSS16.BF2),文字清晰度大幅提升,彻底解决 203 DPI 下字体模糊问题</li>
</ul>
</div>
@@ -747,6 +730,46 @@
});
}
// 用 /api/v1/public/release 返回的 changelog 重渲染更新日志时间线,使客户端
// 发版无需重建官网即可同步。结构与构建时 web/_data/changelog.js 一致;接口
// 不可达或字段缺失时保留构建时静态时间线作 fallback。
function renderChangelog(entries) {
if (!Array.isArray(entries) || entries.length === 0) return;
var dotClass = { '新功能': 'dot-feature', '改进': 'dot-improve', '修复': 'dot-fix' };
var label = { '修复': '问题修复' };
function esc(s) {
return String(s == null ? '' : s).replace(/[&<>"]/g, function(c) {
return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c];
});
}
var html = '';
entries.forEach(function(entry, i) {
var current = i === 0;
html += '<div class="changelog-entry' + (current ? ' current' : '') + '">';
html += '<div class="changelog-meta">';
html += '<div class="changelog-version">v' + esc(entry.version) + '</div>';
html += '<div class="changelog-date">' + esc(entry.date) + '</div>';
if (current) html += '<span class="changelog-tag">当前版本</span>';
html += '</div><div class="changelog-body">';
if (entry.intro) html += '<p class="changelog-intro">' + esc(entry.intro) + '</p>';
(entry.sections || []).forEach(function(section) {
var dot = dotClass[section.type] || 'dot-improve';
var name = label[section.type] || section.type;
html += '<div class="changelog-cat"><div class="changelog-cat-label">';
html += '<span class="dot ' + dot + '"></span>' + esc(name) + '</div><ul>';
(section.items || []).forEach(function(item) {
html += '<li>' + esc(item) + '</li>';
});
html += '</ul></div>';
});
html += '</div></div>';
});
var list = document.getElementById('changelog-list');
if (list) list.innerHTML = html;
var count = document.getElementById('changelog-count');
if (count) count.textContent = '最近 ' + entries.length + ' 个版本。';
}
document.addEventListener('DOMContentLoaded', function() {
var detected = detectPlatform();
updateDetectCard(detected);
@@ -756,6 +779,7 @@
.then(function(r) { return r.json(); })
.then(function(data) {
if (data && data.version) updateVersionBadges(data.version);
if (data && data.changelog) renderChangelog(data.changelog);
if (data && data.download_urls && data.download_urls.macos) {
platforms.macos.btnHref = data.download_urls.macos;
var macBtn = document.getElementById('macos-dl-btn');
@@ -822,6 +846,7 @@
<img src="/assets/logo-full.svg" alt="岩美" />
<p>为酒行与酒店设计的库存、审核、财务一体化管理平台。</p>
<div class="footer-contact">
<div><a href="mailto:yammy2023@163.com">yammy2023@163.com</a></div>
</div>
@@ -854,14 +879,12 @@
<h5>公司</h5>
<ul>
<li><a href="/register/">注册门店</a></li>
<li><a href="/terms/">服务条款</a></li>
<li><a href="/privacy/">隐私政策</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<div>© 2026 岩美科技 · 保留所有权利</div>
<div>沪 ICP 备 2026000000 号 · 沪公网安备 31010000000000 号</div>
</div>
</div>
</footer>
+2 -3
View File
@@ -670,6 +670,7 @@
<img src="/assets/logo-full.svg" alt="岩美" />
<p>为酒行与酒店设计的库存、审核、财务一体化管理平台。</p>
<div class="footer-contact">
<div><a href="mailto:yammy2023@163.com">yammy2023@163.com</a></div>
</div>
@@ -702,14 +703,12 @@
<h5>公司</h5>
<ul>
<li><a href="/register/">注册门店</a></li>
<li><a href="/terms/">服务条款</a></li>
<li><a href="/privacy/">隐私政策</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<div>© 2026 岩美科技 · 保留所有权利</div>
<div>沪 ICP 备 2026000000 号 · 沪公网安备 31010000000000 号</div>
</div>
</div>
</footer>
+2 -3
View File
@@ -707,6 +707,7 @@
<img src="/assets/logo-full.svg" alt="岩美" />
<p>为酒行与酒店设计的库存、审核、财务一体化管理平台。</p>
<div class="footer-contact">
<div><a href="mailto:yammy2023@163.com">yammy2023@163.com</a></div>
</div>
@@ -739,14 +740,12 @@
<h5>公司</h5>
<ul>
<li><a href="/register/">注册门店</a></li>
<li><a href="/terms/">服务条款</a></li>
<li><a href="/privacy/">隐私政策</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<div>© 2026 岩美科技 · 保留所有权利</div>
<div>沪 ICP 备 2026000000 号 · 沪公网安备 31010000000000 号</div>
</div>
</div>
</footer>
+5 -7
View File
@@ -240,8 +240,8 @@ details[open] .faq-q .icon { transform: rotate(45deg); }
<div class="container hero-inner">
<div>
<div class="d-inline-flex items-center gap-8 bg-0 border rounded-pill fs-sm text-gray-7 mb-24" style="padding: 6px 14px 6px 8px;">
<span class="badge badge-brand">v1.0.23</span>
<span>2026-06-07 更新 ·</span>
<span class="badge badge-brand">v1.0.54</span>
<span>2026-06-17 更新 ·</span>
<span class="text-brand fw-5">查看更新</span>
</div>
<h1>从入库到出库,<br/><em>一套系统</em>管到底。</h1>
@@ -605,7 +605,7 @@ details[open] .faq-q .icon { transform: rotate(45deg); }
<li class="d-flex items-start gap-8 fs-sm text-gray-7"><i data-lucide="check" class="icon-sm text-brand flex-shrink-0 mt-2"></i>单门店 · 最多 3 用户</li>
<li class="d-flex items-start gap-8 fs-sm text-gray-7"><i data-lucide="check" class="icon-sm text-brand flex-shrink-0 mt-2"></i>全部模块开放</li>
<li class="d-flex items-start gap-8 fs-sm text-gray-7"><i data-lucide="check" class="icon-sm text-brand flex-shrink-0 mt-2"></i>Web 端 + 移动端</li>
<li class="d-flex items-start gap-8 fs-sm text-gray-7"><i data-lucide="check" class="icon-sm text-brand flex-shrink-0 mt-2"></i>邮件技术支持</li>
<li class="d-flex items-start gap-8 fs-sm text-gray-7"><i data-lucide="check" class="icon-sm text-brand flex-shrink-0 mt-2"></i>微信技术支持</li>
</ul>
<a href="/register/" class="btn btn-secondary w-full justify-center mt-auto">免费开通</a>
</div>
@@ -703,6 +703,7 @@ details[open] .faq-q .icon { transform: rotate(45deg); }
<img src="/assets/logo-full.svg" alt="岩美" />
<p>为酒行与酒店设计的库存、审核、财务一体化管理平台。</p>
<div class="footer-contact">
<div><a href="mailto:yammy2023@163.com">yammy2023@163.com</a></div>
</div>
@@ -715,7 +716,6 @@ details[open] .faq-q .icon { transform: rotate(45deg); }
<li><a href="/#reports">数据洞察</a></li>
<li><a href="/#pricing">价格方案</a></li>
<li><a href="/download/">版本更新</a></li>
<li><a href="/changelog/">更新日志</a></li>
</ul>
</div>
<div class="footer-col">
@@ -736,14 +736,12 @@ details[open] .faq-q .icon { transform: rotate(45deg); }
<h5>公司</h5>
<ul>
<li><a href="/register/">注册门店</a></li>
<li><a href="/terms/">服务条款</a></li>
<li><a href="/privacy/">隐私政策</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<div>© 2026 岩美科技 · 保留所有权利</div>
<div>沪 ICP 备 2026000000 号 · 沪公网安备 31010000000000 号</div>
</div>
</div>
</footer>
+4 -5
View File
@@ -210,7 +210,7 @@
</table>
</div>
<p class="success-note">如忘记门店编码,登录后可在「系统设置 → 关于」中查看。</p>
<p class="success-note">如忘记门店编码,登录后可在「系统设置」中查看。</p>
<a href="/app/" class="btn btn-primary" style="display:inline-flex;align-items:center;gap:8px;">
<i data-lucide="log-in" class="icon"></i>前往登录
</a>
@@ -221,7 +221,7 @@
<script>
(function() {
var API_URL = window.location.origin + '/api/v1/public/register';
var API_URL = "https://jiu.51yanmei.com/api/v1/public/register";
function $(id) { return document.getElementById(id); }
@@ -383,6 +383,7 @@
<img src="/assets/logo-full.svg" alt="岩美" />
<p>为酒行与酒店设计的库存、审核、财务一体化管理平台。</p>
<div class="footer-contact">
<div><a href="mailto:yammy2023@163.com">yammy2023@163.com</a></div>
</div>
@@ -415,14 +416,12 @@
<h5>公司</h5>
<ul>
<li><a href="/register/">注册门店</a></li>
<li><a href="/terms/">服务条款</a></li>
<li><a href="/privacy/">隐私政策</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<div>© 2026 岩美科技 · 保留所有权利</div>
<div>沪 ICP 备 2026000000 号 · 沪公网安备 31010000000000 号</div>
</div>
</div>
</footer>
+43 -2
View File
@@ -390,9 +390,9 @@ pageStyle: |
<section class="section">
<div class="container">
<h2 class="fs-3xl fw-6 text-brand-900 m-0 mb-6" style="letter-spacing: var(--tracking-cn-display);">版本更新日志</h2>
<p class="fs-md text-muted m-0">最近 {{ changelog | length }} 个版本。</p>
<p class="fs-md text-muted m-0" id="changelog-count">最近 {{ changelog | length }} 个版本。</p>
<div class="changelog">
<div class="changelog" id="changelog-list">
{% for entry in changelog %}
<div class="changelog-entry{% if loop.first %} current{% endif %}">
<div class="changelog-meta">
@@ -499,6 +499,46 @@ pageStyle: |
});
}
// 用 /api/v1/public/release 返回的 changelog 重渲染更新日志时间线,使客户端
// 发版无需重建官网即可同步。结构与构建时 web/_data/changelog.js 一致;接口
// 不可达或字段缺失时保留构建时静态时间线作 fallback。
function renderChangelog(entries) {
if (!Array.isArray(entries) || entries.length === 0) return;
var dotClass = { '新功能': 'dot-feature', '改进': 'dot-improve', '修复': 'dot-fix' };
var label = { '修复': '问题修复' };
function esc(s) {
return String(s == null ? '' : s).replace(/[&<>"]/g, function(c) {
return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c];
});
}
var html = '';
entries.forEach(function(entry, i) {
var current = i === 0;
html += '<div class="changelog-entry' + (current ? ' current' : '') + '">';
html += '<div class="changelog-meta">';
html += '<div class="changelog-version">v' + esc(entry.version) + '</div>';
html += '<div class="changelog-date">' + esc(entry.date) + '</div>';
if (current) html += '<span class="changelog-tag">当前版本</span>';
html += '</div><div class="changelog-body">';
if (entry.intro) html += '<p class="changelog-intro">' + esc(entry.intro) + '</p>';
(entry.sections || []).forEach(function(section) {
var dot = dotClass[section.type] || 'dot-improve';
var name = label[section.type] || section.type;
html += '<div class="changelog-cat"><div class="changelog-cat-label">';
html += '<span class="dot ' + dot + '"></span>' + esc(name) + '</div><ul>';
(section.items || []).forEach(function(item) {
html += '<li>' + esc(item) + '</li>';
});
html += '</ul></div>';
});
html += '</div></div>';
});
var list = document.getElementById('changelog-list');
if (list) list.innerHTML = html;
var count = document.getElementById('changelog-count');
if (count) count.textContent = '最近 ' + entries.length + ' 个版本。';
}
document.addEventListener('DOMContentLoaded', function() {
var detected = detectPlatform();
updateDetectCard(detected);
@@ -508,6 +548,7 @@ pageStyle: |
.then(function(r) { return r.json(); })
.then(function(data) {
if (data && data.version) updateVersionBadges(data.version);
if (data && data.changelog) renderChangelog(data.changelog);
if (data && data.download_urls && data.download_urls.macos) {
platforms.macos.btnHref = data.download_urls.macos;
var macBtn = document.getElementById('macos-dl-btn');