尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Resale Master JP - 日本转卖业务财务管理系统 一个面向日本二手转卖业务的私用财务管理 PWA。系统覆盖采购、库存、销售、退货、积分、耗材、买取价对比和税务报表,适合在桌面浏览器和 iPhone 主屏幕 PWA 中使用。檢視完整 README ↗
一个面向日本二手转卖业务的私用财务管理 PWA。系统覆盖采购、库存、销售、退货、积分、耗材、买取价对比和税务报表,适合在桌面浏览器和 iPhone 主屏幕 PWA 中使用。
?tab= 优先。搜索落空时提供「在全部交易中查找」。app/globals.css 里的 SNUtils 风格 CSS 变量@fluentui/react-icons,headless 版)@tanstack/react-table(headless)@tanstack/react-queryInjectManifest,源码 lib/sw/sw-source.ts)npm install
复制 .env.local.example 为 .env.local:
cp .env.local.example .env.local
最小必需配置:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
功能性配置:
KAITORIX_API_TOKENS=your_token1,your_token2
KAITORIX_OPEN_API_KEY=your_open_api_key
KAITORIX_OPEN_API_DAILY_LIMIT=500 # 仅首次响应前的兜底;之后以官方响应头为准
CRON_SECRET=your_random_secret # /api/kaitorix/catalog-sync 的 Cron 鉴权
买取价与目录同步依赖 Kaitorix 官方 Open API(Premium 每日 500 次,每秒 1 次);每日 CSV 同步需要「全部买取数据」下载加购。使用范围与出处标注要求见官方文档 https://kaitorix.app/open/docs 。
在一个全新的 Supabase 项目里,打开 SQL Editor,执行 supabase/schema.sql 即可,一个文件建好所有表、视图、触发器、RLS、Storage bucket 和内置平台数据。
supabase/migrations-archive/ 是历史增量记录,新装不需要执行。
注册第一个用户后,按 schema.sql 文件头的说明把它设为管理员。
npm run dev
resale-master-jp/
├── app/
│ ├── layout.tsx # 根布局、主题初始化、PWA 注册
│ ├── manifest.ts # PWA Manifest
│ ├── globals.css # 设计 token 定义源和全局组件样式
│ ├── fluent-tokens.css # Fluent / Loop 实测 token(浅色 / 深色)
│ ├── api/
│ │ ├── jan-product/[jan]/ # JAN 商品名补全(目录 → 缓存 → search API 兜底)
│ │ ├── kaitorix/ # 买取价查询([jan])、强制刷新、Open API 用量、每日 CSV 同步(catalog-sync)
│ │ ├── thumbnail/enqueue/ # 商品缩略图抓取入队
│ ├── auth/ # 登录、注册、OAuth 回调
│ ├── dashboard/ # 仪表盘
│ ├── transactions/ # 交易列表、新增、详情、编辑
│ ├── supplies/ # 耗材成本管理
│ ├── analytics/ # 数据分析
│ ├── tax-report/ # 税务申报
│ └── settings/ # 设置与支付方式管理
├── components/ # 共用 React 组件
├── contexts/ # AuthContext、PlatformsContext
├── hooks/ # 自定义 hooks
├── lib/
│ ├── api/ # 按业务域划分的 Supabase 调用
│ ├── financial/calculator.ts # ROI 和利润计算
│ ├── supabase/client.ts # Supabase SSR 客户端
│ ├── theme-mode.ts # 深浅色偏好(浅色 / 深色 / 跟随系统)
│ └── theme.ts # 共用 Tailwind class 片段
├── public/
│ ├── sw.js # Service Worker
│ ├── icons/ # PWA 图标
│ └── fonts/ # NotoSansJP(税务 PDF 导出用;界面用系统字体)
├── supabase/schema.sql # 新装唯一入口(完整库结构)
├── supabase/migrations-archive/ # 历史增量记录(新装不需要)
├── scraper/ # 独立服务:缩略图 worker;价格 scraper 仅为原生 App 保留
├── types/database.types.ts # Supabase 类型定义
├── middleware.ts # 路由保护
└── tailwind.config.ts
transactions:采购交易、库存数量、付款拆分、ROI、状态和编辑历史来源。sale_orders:销售订单,一个订单可含多件商品。sales_records:单笔或分批销售记录。return_records:退货记录。payment_methods:支付方式(类型 card / wallet / bank / other、返点率、可选卡号后 4 位)。payment_method_store_rates:支付方式的店铺特殊规则(支付方式 × 采购平台 → 返点率)。coupons / coupon_usage_history:优惠券与使用历史(web 端已移除优惠券功能,表保留供原生 App、LIFF / 小程序使用)。supplies_costs / fixed_costs:耗材与固定成本。points_platforms / purchase_platforms / selling_platforms:积分、采购、销售平台配置。transaction_history:交易字段变更历史。notifications / push_subscriptions:通知与推送订阅(web 端已移除通知功能,表保留供原生 App 使用)。user_preferences:用户级 UI 偏好,如交易列表列设置、默认支付方式(theme_palette 列仅原生 App 使用)。user_roles:管理员角色。user_line_links:用户与 LINE 账号绑定关系(web 端不使用)。kaitorix_price_cache / kaitorix_open_api_usage:单个 JAN 的买取价缓存、Open API 每日用量。kaitorix_catalog:每日同步的买取X 全量商品目录(约 2.6 万件,最新快照),用于输入 JAN 时补全商品名。kaitorix_price_history:买取价历史,每家店对每个 JAN 的报价只在变动时追加一行(price 为空表示不再报价)。kaitorix_scrape_queue:旧的价格抓取队列,web 已不再使用,仅原生 App 仍通过 enqueue_kaitorix_scrape 写入。jan_thumbnail_cache / jan_thumbnail_queue:JAN 维度共享的商品缩略图缓存与抓取队列。upcoming_payments:30 天内待付款(web 已不使用,原生 App 仍在用)。active_coupons:当前可用优惠券(web 端已不使用)。sale_order_summary:销售订单汇总。jan_thumbnail_queue_status:缩略图队列状态监控。set_user_id():插入时自动写入当前用户。update_transaction_status():基于销售和退货记录重算交易状态与 ROI。record_transaction_change():记录交易编辑历史。所有核心业务表启用 RLS,按 auth.uid() 隔离用户数据。管理员读取权限通过 user_roles 与 is_admin() 放宽。
middleware.ts 保护业务页面,/auth/* 和 /api/* 为公开路径。app/manifest.ts 和 public/sw.js,支持 iOS 添加到主屏幕。npm run dev # 启动开发服务器,默认 localhost:3000
npm run build # 生产构建
npm run lint # ESLint 检查
npm run type-check # TypeScript 类型检查
node scripts/scan-design-tokens.mjs # 扫描设计 token 落实情况
项目当前没有 Jest / Vitest / Playwright 测试框架(e2e/specs/ 是空目录占位)。目前没有内置的手动测试入口。
app/fluent-tokens.css(Loop 实测的 Fluent token 浅色 / 深色全量),app/globals.css 的语义 token(--color-* / --label-* / --chart-*)只引用它们;图表色用 Fluent 官方图表配色(DataViz palette)。lib/theme.ts 提供常用卡片、按钮、输入框、布局和提示样式。@fluentui/react-icons/headless/svg/home),选中 / 悬停的实心态用 components/fluent/DualIcon.tsx;避免新增手写 SVG。--loop-font-text / 标题 --loop-font-display,Segoe UI Variable → Apple / Android 系统字体),不加载网页字体。components/Navigation.tsx 组装:桌面(≥768)为透明顶栏 + 左导航(components/shell/NavRail.tsx,展开 / 折叠、「新建」菜单),手机为顶栏 + 底部标签栏。components/shell/SectionDrawer.tsx,页面用 lib/section-drawer.ts 的 useSectionDrawer 注册),手机仍在页面里切换。components/shell/PageHeader.tsx:面包屑 + 操作按钮,放不下的收进「…」菜单),大标题用 heading.page,不写副标题;手机端标题区与按钮保持原样。node scripts/scan-design-tokens.mjs 扫描硬编码色值残留,无标记输出即全部落实。scraper/ 是独立 Node.js 项目,不属于 Next.js PWA 构建,包含两个 worker:
lib/server/jan-thumbnails.ts),scraper 里只剩全量重置脚本 src/reset-thumbnails.ts。
CSV / XLSX 导入后按每批最多 500 个 JAN 等待入队确认,图片由后台抓取。每日 /api/thumbnail/process 先补扫历史漏图交易再处理队列(已有图、已有任务、累计失败 5 次的 JAN 跳过);交易列表与仪表盘缺图时每 5 秒重查,持续最多 2 分钟,无需手动刷新。回归检查:node --test scripts/test-thumbnail-flow.cjs。kaitorix_scrape_queue,用 Playwright 抓价格写回 kaitorix_price_cache。web 端已改走官方 Open API,不再入队;它只为原生 App 保留(原生的价格自动刷新仍通过 enqueue_kaitorix_scrape 入队)。原生端迁到 web 接口之前不要停它。详细启动方式见 scraper/README.md。
.env.local.example 中列出的服务端和客户端变量。scraper/ 不在 Vercel 上运行,需单独托管(pm2,见 scraper/README.md)。