Skip to content

Commit 33c9347

Browse files
committed
Merge branch 'dev': 安装包自建服务器托管与下载页优化
2 parents 5b52cfd + 9bb9061 commit 33c9347

10 files changed

Lines changed: 240 additions & 78 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,62 @@ jobs:
7272
- uses: softprops/action-gh-release@v2
7373
with:
7474
files: release-*/*
75+
76+
# ---------------------------------------------------------------
77+
# 同步 Windows 安装包至自建服务器(国内主下载源 + 自动更新源)
78+
# latest.json 供官网下载页动态展示版本/直链;latest.yml 供 electron-updater
79+
# ---------------------------------------------------------------
80+
- name: Generate latest.json for website
81+
run: |
82+
YML=release-windows-latest/latest.yml
83+
VERSION=$(grep -m1 '^version:' "$YML" | awk '{print $2}')
84+
FILE=$(grep -m1 '^path:' "$YML" | sed 's/^path: //')
85+
SIZE=$(stat -c%s "release-windows-latest/$FILE")
86+
SHA256=$(sha256sum "release-windows-latest/$FILE" | awk '{print $1}')
87+
DATE=$(date -u +%F)
88+
printf '{"version":"%s","fileName":"%s","size":%s,"sha256":"%s","releaseDate":"%s"}\n' \
89+
"$VERSION" "$FILE" "$SIZE" "$SHA256" "$DATE" > release-windows-latest/latest.json
90+
cat release-windows-latest/latest.json
91+
92+
- name: Ensure downloads directory on server
93+
uses: appleboy/ssh-action@v1
94+
with:
95+
host: ${{ secrets.SERVER_HOST }}
96+
username: ${{ secrets.SERVER_USER }}
97+
key: ${{ secrets.SSH_PRIVATE_KEY }}
98+
script: mkdir -p /opt/Entropydecrease/downloads
99+
100+
# 先传二进制(exe/blockmap),后传元数据(yml/json):
101+
# 避免 latest.yml 率先就位时指向尚未上传完成的安装包(更新 404 窗口期)
102+
- name: Upload installer binaries to server
103+
uses: appleboy/scp-action@v0.1.7
104+
with:
105+
host: ${{ secrets.SERVER_HOST }}
106+
username: ${{ secrets.SERVER_USER }}
107+
key: ${{ secrets.SSH_PRIVATE_KEY }}
108+
source: release-windows-latest/*.exe,release-windows-latest/*.blockmap
109+
target: /opt/Entropydecrease/downloads
110+
strip_components: 1
111+
112+
- name: Publish update metadata (last, avoids 404 window)
113+
uses: appleboy/scp-action@v0.1.7
114+
with:
115+
host: ${{ secrets.SERVER_HOST }}
116+
username: ${{ secrets.SERVER_USER }}
117+
key: ${{ secrets.SSH_PRIVATE_KEY }}
118+
source: release-windows-latest/latest.yml,release-windows-latest/latest.json
119+
target: /opt/Entropydecrease/downloads
120+
strip_components: 1
121+
122+
# 保留策略:仅保留最近 3 个版本的安装包,防止磁盘增长
123+
- name: Prune old versions (keep last 3)
124+
uses: appleboy/ssh-action@v1
125+
with:
126+
host: ${{ secrets.SERVER_HOST }}
127+
username: ${{ secrets.SERVER_USER }}
128+
key: ${{ secrets.SSH_PRIVATE_KEY }}
129+
script: |
130+
cd /opt/Entropydecrease/downloads
131+
ls -t -- *.exe 2>/dev/null | tail -n +4 | while read -r f; do
132+
rm -f -- "$f" "$f.blockmap"
133+
done

‎client/electron-builder.yml‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
# Electron Builder 打包配置 - 熵减桌面端
22
appId: com.entropydecrease.app
33
productName: "Entropy decrease"
4+
# 双发布源:第一项(generic = 自建服务器)被写入 app-update.yml 作为
5+
# electron-updater 的自动更新源;GitHub 保留为开源分发/灾备源。
6+
# 注意:存量客户端的 app-update.yml 仍指向 GitHub,过渡期内
7+
# GitHub Release 资产(含 latest.yml)不可停发,否则存量用户无法升级到新源。
48
publish:
5-
provider: github
6-
owner: Aparencia
7-
repo: Entropydecrease
9+
- provider: generic
10+
url: https://entropydecrease.com/downloads
11+
- provider: github
12+
owner: Aparencia
13+
repo: Entropydecrease
14+
# 统一产物命名(无空格):避免默认 "Entropy decrease Setup x.y.z.exe"
15+
# 在 URL/服务器文件名中产生空格转义问题
816
directories:
917
output: release
1018
buildResources: build
19+
artifactName: "Entropydecrease-Setup-${version}.${ext}"
1120
asarUnpack:
1221
- "**/*.node"
1322
files:

‎docs/knowledge/bugs/2026-07-reduced-motion-fade-in-up-invisible.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,4 @@ computedStyle: opacity="0", animationPlayState="paused", animationFillMode="none
8484

8585
- [web.dev — prefers-reduced-motion](https://web.dev/articles/prefers-reduced-motion)
8686
- 修复提交涉及文件:`client/src/index.css`
87-
- 关联特性:v0.26.0 学习启动仪式(`client/src/features/dashboard/components/ritual/`)
87+
- 关联特性:v0.27.0 学习启动仪式(`client/src/features/dashboard/components/ritual/`)
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
# 熵减 v0.26.0 版本迭代计划
1+
# 熵减 v0.27.0 版本迭代计划
22

3-
> **版本**:v0.26.0
3+
> **版本**:v0.27.0
44
> **主题**:学习启动仪式体验重塑——呼吸容器 · 主动提取 · 数据闭环
55
> **阶段**:产品打磨期
6-
> **状态**:规划中
6+
> **状态**:已交付
77
> **创建日期**:2026-07-30
88
> **最后更新**:2026-07-30
99
1010
---
1111

1212
## 一、版本概述
1313

14-
### 1.1 v0.26.0 定位
14+
### 1.1 v0.27.0 定位
1515

1616
熵减 v0.25.0 已完成品牌迁移(课伴 → 熵减)与全仓规范化重构。学习启动仪式(FEAT-017)已在此前版本交付基础版三步流程(回顾闪回 + 微目标 + Box Breathing),但存在规格缺口与体验天花板:
1717

@@ -21,15 +21,15 @@
2121
- **可用性缺口**:"不再显示"无 UI 入口、无键盘导航/焦点陷阱、无 `prefers-reduced-motion` 支持
2222
- **三步割裂**:三个独立屏幕切换,缺乏"从生活到学习"的连续心理过渡
2323

24-
v0.26.0 以一次完整头脑风暴(25 项创意全采纳,见第二章)为输入,将启动仪式从"三个弹窗"重塑为**"一次被呼吸包裹的连续体验"**,同时让回顾/目标环节产生真实数据闭环,并为老用户提供自适应轻量路径。
24+
v0.27.0 以一次完整头脑风暴(25 项创意全采纳,见第二章)为输入,将启动仪式从"三个弹窗"重塑为**"一次被呼吸包裹的连续体验"**,同时让回顾/目标环节产生真实数据闭环,并为老用户提供自适应轻量路径。
2525

2626
| 版本 | 定位 | 状态 |
2727
|------|------|------|
2828
| v0.23.0 | 阶段性工作总结 | ✅ 已交付 |
2929
| v0.24.0 | 迭代积累 | ✅ 已交付 |
3030
| v0.25.0 | 熵减品牌迁移与全仓规范化重构 | ✅ 已交付 |
31-
| **v0.26.0** | **学习启动仪式体验重塑** | 🔄 规划中 |
32-
| v0.27.0+ | 依据 v0.26.0 使用数据迭代自适应参数与 A/B 裁决 | 📋 Backlog |
31+
| **v0.27.0** | **学习启动仪式体验重塑** | ✅ 已交付 |
32+
| v0.28.0+ | 依据 v0.27.0 使用数据迭代自适应参数与 A/B 裁决 | 📋 Backlog |
3333

3434
### 1.2 版本输入来源
3535

@@ -52,9 +52,9 @@ v0.26.0 以一次完整头脑风暴(25 项创意全采纳,见第二章)为
5252

5353
### 1.4 边界声明
5454

55-
**v0.26.0 做**:呼吸容器架构重塑、记忆挑战卡、掌握标记闭环、目标接力与快选标签、主题化呼吸生命体、呼吸引导音、光尘转场、今日学习卡、仪式火种、自适应编排引擎(机制交付)、AI 回顾小问(含离线降级)、目标下压番茄钟、语音目标、交互式呼吸、结构顺序 A/B 机制、全部工程补课项
55+
**v0.27.0 做**:呼吸容器架构重塑、记忆挑战卡、掌握标记闭环、目标接力与快选标签、主题化呼吸生命体、呼吸引导音、光尘转场、今日学习卡、仪式火种、自适应编排引擎(机制交付)、AI 回顾小问(含离线降级)、目标下压番茄钟、语音目标、交互式呼吸、结构顺序 A/B 机制、全部工程补课项
5656

57-
**v0.26.0 不做**:自适应编排的参数调优(需真实使用数据积累,v0.27.0)、结构顺序 A/B 的最终裁决(依赖上线后完成率数据,v0.27.0)、仪式数据接入学习仪表盘深度分析(依赖仪表盘重构,后续版本)、多套呼吸法扩展(4-7-8 呼吸等,Backlog)
57+
**v0.27.0 不做**:自适应编排的参数调优(需真实使用数据积累,v0.28.0)、结构顺序 A/B 的最终裁决(依赖上线后完成率数据,v0.28.0)、仪式数据接入学习仪表盘深度分析(依赖仪表盘重构,后续版本)、多套呼吸法扩展(4-7-8 呼吸等,Backlog)
5858

5959
---
6060

@@ -94,7 +94,7 @@ v0.26.0 以一次完整头脑风暴(25 项创意全采纳,见第二章)为
9494

9595
| 冲突 | 裁决 |
9696
|------|------|
97-
| RIT-01 呼吸即容器 vs RIT-03 倒置结构 | RIT-01 为主架构;RIT-03 降级为 A/B 微决策(开场是否先纯呼吸 1 圈),v0.26.0 交付双路径与埋点机制,v0.27.0 依据完成率裁决 |
97+
| RIT-01 呼吸即容器 vs RIT-03 倒置结构 | RIT-01 为主架构;RIT-03 降级为 A/B 微决策(开场是否先纯呼吸 1 圈),v0.27.0 交付双路径与埋点机制,v0.28.0 依据完成率裁决 |
9898
| RIT-02 自适应编排 vs RIT-04 强度自选 | 合并为一个系统:RIT-04 是用户手动设定的"偏好上限",RIT-02 在偏好范围内自动微调;手动优先于自动 |
9999

100100
其余互补关系:RIT-05 是 RIT-08 的离线基线;RIT-11 与 RIT-12 为并存输入方式;RIT-14/15/16 为并存可选项。
@@ -211,7 +211,7 @@ v0.26.0 以一次完整头脑风暴(25 项创意全采纳,见第二章)为
211211

212212
**方案**:
213213
- `RitualSettings` 扩展:`{ enabled, lastRitualDate, skipToday, intensity: 'light'|'standard'|'deep', autoAdapt: boolean }`
214-
- `ritualPlanner.ts` 编排规则(v0.26.0 交付机制,参数写死为保守初值):
214+
- `ritualPlanner.ts` 编排规则(v0.27.0 交付机制,参数写死为保守初值):
215215
- 无上次会话数据 → 裁剪回顾步骤
216216
- 连续完成 ≥7 天且 `autoAdapt=true` → 默认轻档(呼吸 1 圈 + 目标一行)
217217
- 22:00 后 → 放松版文案与更暗视觉
@@ -317,7 +317,7 @@ v0.26.0 以一次完整头脑风暴(25 项创意全采纳,见第二章)为
317317

318318
**验收标准**:无 P0/P1 缺陷;呼吸动画在低端设备 ≥30fps 或正确降级;离线全流程可完成仪式;`npm run build` 与 `npm run electron:build` 成功。
319319

320-
**里程碑**:M-RC — v0.26.0 Release Candidate。
320+
**里程碑**:M-RC — v0.27.0 Release Candidate。
321321

322322
---
323323

@@ -366,7 +366,7 @@ Beta.1(智能与进阶,依赖 Alpha.2)
366366
| **M-A1** | Alpha.1 | Week 1-2 | 组件拆分 + 性能/a11y 修复 + 挑战卡 + 掌握/目标数据闭环 |
367367
| **M-A2** | Alpha.2 | Week 3-5 | 呼吸容器 + 主题生命体 + 引导音 + 光尘转场 + 情感层 |
368368
| **M-B1** | Beta.1 | Week 6-7 | 自适应编排 + AI 小问 + 番茄钟联动 + 进阶交互 + A/B 机制 |
369-
| **M-RC** | RC | Week 8 | v0.26.0 Release Candidate |
369+
| **M-RC** | RC | Week 8 | v0.27.0 Release Candidate |
370370

371371
**总预估工期**:8 周。
372372

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@
3030
},
3131
"lint-staged": {
3232
"client/**/*.{ts,tsx}": "npm --prefix client exec oxlint --",
33-
"website/**/*.{ts,tsx}": "npm --prefix website exec eslint --"
33+
"website/**/*.{ts,tsx}": "npm --prefix website exec eslint -- --config website/eslint.config.mjs"
3434
}
3535
}

‎server/deploy.sh‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,14 @@ fi
6767
log_info "$ENV_FILE 已就绪 ✓"
6868

6969
# ---------------------------------------------------------------------------
70-
# 3. 构建并启动服务
70+
# 3. 准备宿主机目录(Nginx bind mount 依赖,缺失时 Docker 会以 root 自动创建,
71+
# 提前创建保证 CI 用户可写入)
72+
# ---------------------------------------------------------------------------
73+
log_info "准备静态资源目录..."
74+
mkdir -p /opt/Entropydecrease/website /opt/Entropydecrease/downloads
75+
76+
# ---------------------------------------------------------------------------
77+
# 4. 构建并启动服务
7178
# ---------------------------------------------------------------------------
7279
log_info "构建 Docker 镜像(首次构建约需 3-5 分钟)..."
7380

@@ -78,13 +85,13 @@ log_info "启动所有服务..."
7885
docker compose -f docker-compose.prod.yml --env-file "$ENV_FILE" up -d
7986

8087
# ---------------------------------------------------------------------------
81-
# 4. 等待服务就绪
88+
# 5. 等待服务就绪
8289
# ---------------------------------------------------------------------------
8390
log_info "等待服务启动..."
8491
sleep 10
8592

8693
# ---------------------------------------------------------------------------
87-
# 5. 健康检查
94+
# 6. 健康检查
8895
# ---------------------------------------------------------------------------
8996
log_info "执行健康检查..."
9097

‎server/docker-compose.prod.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ services:
146146
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
147147
- ./nginx/certs:/etc/nginx/certs:ro
148148
- /opt/Entropydecrease/website:/usr/share/nginx/html:ro
149+
# 安装包下载目录:独立于 website(其部署会 rm 清空目录),由 release.yml 同步
150+
- /opt/Entropydecrease/downloads:/usr/share/nginx/downloads:ro
149151
depends_on:
150152
- ai-gateway
151153
- sync-service

‎server/nginx/nginx.conf‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ http {
2525
# Rate limiting
2626
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/m;
2727
limit_req_zone $binary_remote_addr zone=ai:10m rate=30r/m;
28+
# 安装包下载并发限制(按 IP),避免大文件下载挤占 API 带宽
29+
limit_conn_zone $binary_remote_addr zone=dl_conn:10m;
2830

2931
# Upstream 后端服务
3032
upstream ai_gateway {
@@ -188,6 +190,26 @@ http {
188190
proxy_set_header Host $host;
189191
}
190192

193+
# -----------------------------------------------------------------
194+
# 安装包下载目录(由 release.yml CI 同步至 /opt/Entropydecrease/downloads)
195+
# ^~ 阻止服务器级正则 location(如图片/字体规则)抢占匹配;
196+
# 同时作为 electron-updater generic provider 的更新源
197+
# -----------------------------------------------------------------
198+
location ^~ /downloads/ {
199+
root /usr/share/nginx;
200+
autoindex off;
201+
# 单连接限速 2MB/s + 单 IP 最多 4 并发,保护 AI 网关/同步服务带宽
202+
limit_rate 2m;
203+
limit_conn dl_conn 4;
204+
205+
# 更新元数据(latest.yml / latest.json)禁止缓存,
206+
# 否则客户端会长期读到旧版本信息;允许 www 子域跨域读取
207+
location ~* \.(yml|json)$ {
208+
add_header Cache-Control "no-cache" always;
209+
add_header Access-Control-Allow-Origin "*" always;
210+
}
211+
}
212+
191213
# -----------------------------------------------------------------
192214
# 官网静态站点(Next.js 静态导出,由 CI 同步至 /opt/Entropydecrease/website)
193215
# -----------------------------------------------------------------

‎website/app/download/page.tsx‎

Lines changed: 5 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// @ai-context
2-
// 下载页:应用窗口 Mockup、下载入口、版本轨迹与开源信息。Download page: app mockup, download CTA, changelog.
2+
// 下载页:应用窗口 Mockup、下载入口(DownloadCta 服务器直链 + GitHub 备用)、版本轨迹与开源信息。
3+
// Download page: app mockup, download CTA (server-hosted with GitHub fallback), changelog.
34
// Why: Mockup 为纯 CSS 风格化示意而非截图,避免版本迭代后截图过期。
45
"use client";
56

67
import { motion } from "framer-motion";
8+
import { DownloadCta } from "@/components/DownloadCta";
79
import { GlowOrb } from "@/components/GlowOrb";
810
import { SectionReveal } from "@/components/SectionReveal";
911

@@ -46,13 +48,6 @@ const CHANGELOG = [
4648
},
4749
];
4850

49-
const SYSTEM_REQ = [
50-
{ label: "操作系统", value: "Windows 10 / 11 (64位)" },
51-
{ label: "处理器", value: "Intel i5 / AMD Ryzen 5 或更高" },
52-
{ label: "内存", value: "8 GB RAM 以上" },
53-
{ label: "存储空间", value: "500 MB 可用空间" },
54-
];
55-
5651
/* ---------- 应用窗口 Mockup ---------- */
5752

5853
function AppMockup() {
@@ -182,57 +177,10 @@ export default function DownloadPage() {
182177
</SectionReveal>
183178
</section>
184179

185-
{/* 下载区 */}
180+
{/* 下载区(服务器直链 + 动态版本 + GitHub 备用源) */}
186181
<section className="max-w-3xl mx-auto px-6 mb-24">
187182
<SectionReveal>
188-
<div
189-
className="rounded-3xl p-10 text-center"
190-
style={{
191-
background: "var(--kb-bg-elevated)",
192-
border: "1px solid var(--kb-glass-border)",
193-
boxShadow: "var(--kb-shadow-brand)",
194-
}}
195-
>
196-
<div className="flex items-center justify-center gap-3 mb-6">
197-
<span
198-
className="w-12 h-12 rounded-2xl flex items-center justify-center text-lg font-bold text-white"
199-
style={{ background: "linear-gradient(135deg, var(--kb-brand-400), var(--kb-accent-500))" }}
200-
>
201-
熵
202-
</span>
203-
<div className="text-left">
204-
<h2 className="font-serif text-xl font-bold text-kb-text">熵减 Entropydecrease</h2>
205-
<p className="text-xs text-kb-text3">v0.15.0 正式版 · 2026-07</p>
206-
</div>
207-
</div>
208-
209-
<a
210-
href="https://github.com/Aparencia/Entropydecrease/releases/latest"
211-
target="_blank"
212-
rel="noopener noreferrer"
213-
className="inline-block px-12 py-4 rounded-2xl text-white font-medium text-lg transition-all duration-500 hover:scale-[1.04] active:scale-[0.97] mb-6"
214-
style={{
215-
background: "linear-gradient(135deg, var(--kb-amber), var(--kb-accent-400))",
216-
boxShadow: "var(--kb-shadow-accent)",
217-
}}
218-
>
219-
⬇ 下载 Windows 版
220-
</a>
221-
222-
<p className="text-xs text-kb-text3 mb-8">
223-
约 120 MB · 适用于 Windows 10/11 (64位) · 免费开源
224-
</p>
225-
226-
{/* 系统要求 */}
227-
<div className="grid grid-cols-2 sm:grid-cols-4 gap-4 text-left">
228-
{SYSTEM_REQ.map((req) => (
229-
<div key={req.label} className="rounded-xl p-3.5" style={{ background: "var(--kb-bg-tertiary)" }}>
230-
<p className="text-[10px] text-kb-text3 uppercase tracking-wider mb-1">{req.label}</p>
231-
<p className="text-xs text-kb-text2 leading-snug">{req.value}</p>
232-
</div>
233-
))}
234-
</div>
235-
</div>
183+
<DownloadCta />
236184
</SectionReveal>
237185
</section>
238186

0 commit comments

Comments
 (0)