自己的衣橱程序
Go to file
jif2.zhang 84fb01b8a3
Some checks failed
Android Build & Publish / build-android (push) Failing after 5s
Docker Build and Push / build-image (push) Failing after 4m32s
feat: 自动部署 + android 每次提交触发
- docker-build.yml: main 分支推送 → 构建 OTA 包 → Docker 镜像 → :3002 自动部署
- Dockerfile: node:22-alpine, dist + server + ota-package, healthcheck
- android-build.yml: 触发改为 on push (所有分支), 每次提交都构建
- ota-package/README.md 占位, 本地 docker build 不报错
- .gitignore / .dockerignore 调整
2026-09-11 17:12:58 +08:00
.gitea/workflows feat: 自动部署 + android 每次提交触发 2026-09-11 17:12:58 +08:00
ota-package feat: 自动部署 + android 每次提交触发 2026-09-11 17:12:58 +08:00
photograph init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
prototype init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
scripts init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
server init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
src init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
src-tauri init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
.dockerignore feat: 自动部署 + android 每次提交触发 2026-09-11 17:12:58 +08:00
.gitignore feat: 自动部署 + android 每次提交触发 2026-09-11 17:12:58 +08:00
.mise.toml init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
DESIGN.md init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
Dockerfile feat: 自动部署 + android 每次提交触发 2026-09-11 17:12:58 +08:00
index.html init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
MCP.md init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
package-lock.json init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
package.json init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
README.md init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
tsconfig.json init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00
vite.config.ts init: Wardrobe 衣物管理系统 - 项目首页、OTA 升级、Android CI/CD 2026-09-11 15:46:42 +08:00

Wardrobe - AI 衣物管理系统

基于 Tauri 2.x 封装的跨平台衣物管理应用,目标平台包括 Android / Windows / macOS

功能特性

  • 📸 数字衣橱 - 拍照录入、AI 识别、分类管理
  • 💡 AI 搭配推荐 - 按季节/场合智能推荐
  • 📅 穿搭日历 - 记录每日 OOTD
  • 📊 风格统计 - 衣橱利用率、分类分析
  • 🧺 清洁管理 - 清洁周期提醒
  • 🔐 邮箱/手机注册 - 验证码认证 (暂定 1111)
  • 🗄️ MCP 服务 - AI 平台数据管理接口
  • 🦆 DuckDB - 本地嵌入式数据库

技术栈

技术
前端 React 18 + TypeScript + Vite + Zustand
桌面壳 Tauri 2 (WebView)
后端 Rust + DuckDB (bundled)
移动端 Tauri Android
状态管理 Zustand
路由 React Router v6

目录结构

├── src/                     # React 前端
│   ├── api/                 # Tauri IPC 封装
│   ├── components/          # 通用组件 (Layout)
│   ├── pages/               # 页面
│   │   ├── Landing.tsx      # 项目首页 (响应式, 含 APK 下载)
│   │   ├── Login.tsx        # 登录/注册 (邮箱/手机 + 验证码)
│   │   ├── Home.tsx         # 首页/今日推荐
│   │   ├── Closet.tsx       # 衣橱列表
│   │   ├── AddClothing.tsx  # 添加衣物
│   │   ├── ClothingDetail.tsx
│   │   ├── Outfits.tsx      # 搭配推荐
│   │   ├── Calendar.tsx     # 穿搭日历
│   │   └── Profile.tsx      # 我的 (含 OTA 升级区)
│   ├── api/
│   │   ├── index.ts         # Tauri IPC 封装
│   │   └── ota.ts           # OTA 封装 (Tauri + Web 双路径)
│   ├── version.ts           # 版本/构建号 (vite define 注入)
│   ├── stores/              # Zustand 状态
│   ├── styles/              # 全局样式
│   └── types/               # TS 类型
├── server/                  # OTA 服务端 (Express)
│   ├── index.js             # 静态 dist + SPA fallback + /api/health
│   └── routes/ota.js        # OTA check/bundle/manifest-web 接口
├── scripts/
│   ├── build-ota.mjs        # OTA 打包 + minisign 签名 + latest.json
│   ├── ota-genkey.mjs       # 生成 minisign 密钥对
│   ├── upload-ota-r2.sh     # OTA 包上传 R2
│   └── ...                  # Android 构建/签名/上传脚本
├── src-tauri/               # Rust 后端
│   ├── src/
│   │   ├── main.rs          # 桌面入口 (薄壳)
│   │   ├── lib.rs           # 应用逻辑 + mobile_entry_point + hotswap 插件
│   │   ├── db.rs            # DuckDB 数据层
│   │   ├── models.rs        # 数据模型
│   │   ├── auth.rs          # 认证 (验证码 1111)
│   │   └── mcp.rs           # MCP 服务
│   ├── Cargo.toml
│   ├── tauri.conf.json      # 含 plugins.hotswap (OTA 端点 + 公钥)
│   └── capabilities/default.json
├── prototype/               # HTML 交互原型
└── photograph/              # 竞品截图

快速开始

前置要求

开发

npm install
npm run tauri dev          # 桌面端开发

Android 构建

npm run tauri android init  # 首次生成 Android 工程
npm run tauri android dev    # Android 设备调试
npm run tauri android build  # 生成 APK

关键设计

数据库 (DuckDB)

  • 数据文件: %APP_DATA%/wardrobe/wardrobe.duckdb, Android 下存于应用私有目录
  • 表: users, clothing_items, outfits, daily_records
  • 读写均通过 Mutex<Connection> 串行化,保证线程安全

优雅停机

  • ctrlc 信号捕获 → 设置 shutdown flag
  • 窗口关闭事件 → 记录日志、释放连接
  • DuckDB 连接在进程结束时由 OS 正常关刷

验证码 (临时)

  • 统一固定为 1111
  • 有效期 5 分钟,成功后自失效
  • 注册: 邮箱 或 手机号 (二选一) + 1111

MCP 服务

详见 MCP.md。通过 mcp_list_tools / mcp_call_tool IPC 命令暴露 10 个数据管理工具。

Android CI/CD

参考 D:\workbench\iboard 的 Gitea Actions 部署模式。

触发方式

推送 android-* 分支 (如 android/release) 自动触发构建。

流程 (.gitea/workflows/android-build.yml)

push android-* → checkout → mise( node/rust ) → JDK 17
  → 定位可复用 Android SDK (优先 runner 预装 /usr/local/lib/android/sdk, 其次 CI 缓存, 最后下载)
  → 缓存复用 NDK 27.2 / Rust 工具链 / Tauri target
  → tauri android init --ci
  → 从配置中心拉取全部密钥 (签名 + R2)
  → scripts/ci/android-signing.sh 注入签名
  → tauri android build --apk → 断言签名生效
  → scripts/upload-r2.sh 用 wrangler 上传 APK 到 R2 公开桶 (store/data/android/wardrobe.apk)
  → 输出公共下载地址 (https://pub-...r2.dev/data/android/wardrobe.apk)

CI secrets (仅配置中心连接)

Secret 说明
CONFIG_CENTER_URL 配置中心地址 (未设时回退 http://bh.vps.honor3.com:8008)
CONFIG_CENTER_TOKEN 配置中心访问 token

所有业务密钥 (签名 keystore / R2 token) 一律来自配置中心,不进 Gitea secrets。

配置中心存储约定

项目 分组 key 用途
service-wardrobe signing ANDROID_KEYSTORE_B64 keystore base64 (JKS RSA 2048)
service-wardrobe signing ANDROID_KEY_ALIAS wardrobe
service-wardrobe signing ANDROID_KEY_PASSWORD store/key 密码
service-wardrobe ota MINISIGN_PRIVATE_KEY OTA 包 minisign 私钥 (整段 .key, 多行)
service-wardrobe ota CF_OTA_ENDPOINT OTA 检查端点 (部署参考)
CommonExternalService cloudflare r2/CF_API_TOKEN Cloudflare API token (wrangler 上传)
CommonExternalService cloudflare r2/CF_R2_PUBLIC_URL R2 公共访问域名

CI 的 Fetch config center 步骤拉取以上全部 key 注入环境变量,签名与上传步骤均不再依赖 Gitea secrets。 建议用 CONFIG_CENTER_TOKEN 为配置中心加鉴权(当前 REST API 无鉴权,任何人可读/写)。

本地构建 (可选, WSL)

bash scripts/build-apk.sh debug     # 或 release
# 脚本自动复用本机 Android SDK/NDK (~/android-sdk, NDK 27.2.x)

项目首页 (Landing)

/ 为公开的项目首页 (src/pages/Landing.tsx),响应式适配桌面与手机 web

  • 项目简介 + 功能特性 + 技术栈
  • APK 下载: 按钮直链 R2 公共桶 https://pub-...r2.dev/data/android/wardrobe.apk(由 android-build.yml 上传),附版本号、复制链接与安装提示
  • web 新版本提示: 启动时请求 /api/ota/manifest-web,有新构建号时底部浮出"刷新"横幅
  • 登录后的应用首页迁移到 /home(底部导航同步更新)

部署: npm run build && OTA_PACKAGE_DIR=ota-package npm startserver 同时托管首页 dist 与 OTA 接口。

OTA 升级

参考 iboard,采用 tauri-plugin-hotswap 前端热替换方案minisign 签名 + 下载 + 校验 + 原子替换),升级不经过应用市场。

原理

  • Tauri 客户端: 启动时 notifyReady();检查更新走插件内置 checkUpdate(),下载/校验/替换/回滚均由插件完成(公钥在 src-tauri/tauri.conf.jsonplugins.hotswap.pubkey,端点在 plugins.hotswap.endpoint
  • Web 浏览器: 只比对 /api/ota/manifest-webbuild_id 与当前 BUILD_ID提示刷新Vite 指纹会缓存失效)
  • 构建号 __BUILD_ID__YYYYMMDD.HHmmssvite.config.ts 每次构建注入

服务端 (server/)

接口 说明
GET /api/ota/check/:seq 有新包 → 200 + manifest无 → 204
GET /api/ota/bundle/:file 下载 tar.gz 升级包 (流式)
GET /api/ota/manifest-web Web 简化版 manifest
GET /api/health 健康检查

数据源: 环境变量 OTA_PACKAGE_DIR(默认 ota-package/)下的 latest.json + wardrobe-ota.tar.gzPORT 默认 3002(与 iboard 的 3001 同机共存)。可选 OTA_PUBLIC_BASE 让客户端直连 R2 下载 bundle。

本地生成 OTA 包

npm run build                 # 先构建 dist
minisign -G -W -p ota-package/hotswap.pub -s ota-package/hotswap.key  # 或 npm run ota:genkey
npm run build:ota -- --notes "v0.2 更新说明"   # 打包 + 签名 + 写 latest.json
npm start                     # 起服务, 手动验收 /api/ota/*

首次需安装 minisignWindows: scoop/choco 或官方 win64 二进制)。 生成的 hotswap.key 请存到配置中心 service-wardrobe / ota / MINISIGN_PRIVATE_KEY(不要提交 git hotswap.pub 的公钥行写入 src-tauri/tauri.conf.json

OTA 发布 CI (.gitea/workflows/ota-build.yml)

手动 workflow_dispatch 触发:

build frontend → npm run build
  → apt install minisign
  → 从配置中心拉取 MINISIGN_PRIVATE_KEY (service-wardrobe/ota) + CF_API_TOKEN (cloudflare)
  → node scripts/build-ota.mjs 打包+签名
  → scripts/upload-ota-r2.sh 上传到 R2 (store/ota/wardrobe-ota.tar.gz + latest.json)

客户端升级操作

「我的」页 → 「检查更新 (OTA)」:

  • 检查更新 / 立即升级(带进度)/ 回滚(仅 OTA 覆盖时显示)
  • Web 端仅可检查新构建号提示刷新

mise 本地工具链

本项目用 mise 统一管理 Node/npm/Rust 版本,仓库根目录 .mise.toml 声明工具版本,cd 进入目录后自动激活。

[tools]
node = "24.21.0"
npm  = "12.0.2"
rust = "stable"

Windows 安装 (已完成)

  1. 下载 mise-v*-windows-x64.zip → 解压到 ~\.local\bin\mise.exe
  2. 用户 PATH 追加: ~\.local\bin~\AppData\Local\mise\shims
  3. PowerShell $PROFILE 添加: & "$env:USERPROFILE\.local\bin\mise.exe" activate powershell
  4. mise use -g node@24.21.0 npm@12.0.2 rust@stable 安装全局工具

注意: Windows 下 mise 数据目录在 ~\AppData\Local\miseshims 位于 ~\AppData\Local\mise\shims (非 ~\.local\share\mise\shims)。

原型

浏览器打开 prototype/index.html 查看可交互原型。

License

Private