chore: 初始化项目结构与蓝图
- 配置 pnpm workspace monorepo 基础结构 - 初始化 .blueprint/ 蓝图:6 个业务模块、21 张任务卡 - 目标:Z Fold 6 折叠屏不动产物品摸底统计 App(React Native + Expo) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
a0929de768
222
.blueprint/manifest.yaml
Normal file
222
.blueprint/manifest.yaml
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
version: 1
|
||||||
|
name: react-phone-apps
|
||||||
|
iteration: 1
|
||||||
|
updated: 2026-04-07
|
||||||
|
|
||||||
|
areas:
|
||||||
|
- id: infrastructure
|
||||||
|
name: 基础设施
|
||||||
|
color: "#6B7280"
|
||||||
|
- id: shared
|
||||||
|
name: 共享层
|
||||||
|
color: "#8B5CF6"
|
||||||
|
- id: data
|
||||||
|
name: 数据层
|
||||||
|
color: "#F59E0B"
|
||||||
|
- id: rn-app
|
||||||
|
name: RN 应用(不动产摸底)
|
||||||
|
color: "#10B981"
|
||||||
|
- id: frontend
|
||||||
|
name: 前端应用(Web)
|
||||||
|
color: "#3B82F6"
|
||||||
|
|
||||||
|
modules:
|
||||||
|
# ── 基础设施 ──────────────────────────────────────────────────
|
||||||
|
- id: monorepo-setup
|
||||||
|
name: Monorepo 工程配置
|
||||||
|
area: infrastructure
|
||||||
|
status: done
|
||||||
|
progress: 100
|
||||||
|
position: [80, 80]
|
||||||
|
|
||||||
|
# ── 共享层 ────────────────────────────────────────────────────
|
||||||
|
- id: shared-ui
|
||||||
|
name: 共享 UI 组件库
|
||||||
|
area: shared
|
||||||
|
status: concept
|
||||||
|
progress: 0
|
||||||
|
position: [380, 80]
|
||||||
|
|
||||||
|
- id: shared-utils
|
||||||
|
name: 共享工具函数库
|
||||||
|
area: shared
|
||||||
|
status: concept
|
||||||
|
progress: 0
|
||||||
|
position: [380, 240]
|
||||||
|
|
||||||
|
- id: shared-hooks
|
||||||
|
name: 共享 React Hooks
|
||||||
|
area: shared
|
||||||
|
status: concept
|
||||||
|
progress: 0
|
||||||
|
position: [380, 400]
|
||||||
|
|
||||||
|
- id: shared-types
|
||||||
|
name: 共享类型定义
|
||||||
|
area: shared
|
||||||
|
status: concept
|
||||||
|
progress: 0
|
||||||
|
position: [380, 560]
|
||||||
|
|
||||||
|
# ── 数据层 ────────────────────────────────────────────────────
|
||||||
|
- id: local-data-layer
|
||||||
|
name: 本地数据持久化层
|
||||||
|
area: data
|
||||||
|
status: planned
|
||||||
|
progress: 0
|
||||||
|
position: [680, 80]
|
||||||
|
|
||||||
|
# ── RN 应用(不动产摸底)────────────────────────────────────
|
||||||
|
- id: survey-app-shell
|
||||||
|
name: 应用外壳与折叠屏布局
|
||||||
|
area: rn-app
|
||||||
|
status: planned
|
||||||
|
progress: 0
|
||||||
|
position: [980, 80]
|
||||||
|
|
||||||
|
- id: floor-map
|
||||||
|
name: 楼层地图与标记点管理
|
||||||
|
area: rn-app
|
||||||
|
status: planned
|
||||||
|
progress: 0
|
||||||
|
position: [980, 280]
|
||||||
|
|
||||||
|
- id: item-form
|
||||||
|
name: 物品登记表单
|
||||||
|
area: rn-app
|
||||||
|
status: planned
|
||||||
|
progress: 0
|
||||||
|
position: [980, 480]
|
||||||
|
|
||||||
|
- id: photo-capture
|
||||||
|
name: 照片采集与管理
|
||||||
|
area: rn-app
|
||||||
|
status: planned
|
||||||
|
progress: 0
|
||||||
|
position: [980, 680]
|
||||||
|
|
||||||
|
- id: inventory-summary
|
||||||
|
name: 汇总列表与统计
|
||||||
|
area: rn-app
|
||||||
|
status: planned
|
||||||
|
progress: 0
|
||||||
|
position: [980, 880]
|
||||||
|
|
||||||
|
# ── 前端应用(Web,预留)──────────────────────────────────────
|
||||||
|
- id: app-scaffold
|
||||||
|
name: 应用脚手架模板
|
||||||
|
area: frontend
|
||||||
|
status: concept
|
||||||
|
progress: 0
|
||||||
|
position: [1280, 80]
|
||||||
|
|
||||||
|
- id: routing
|
||||||
|
name: 路由与页面结构
|
||||||
|
area: frontend
|
||||||
|
status: concept
|
||||||
|
progress: 0
|
||||||
|
position: [1280, 240]
|
||||||
|
|
||||||
|
- id: theming
|
||||||
|
name: 主题与样式系统
|
||||||
|
area: frontend
|
||||||
|
status: concept
|
||||||
|
progress: 0
|
||||||
|
position: [1280, 400]
|
||||||
|
|
||||||
|
- id: state-management
|
||||||
|
name: 全局状态管理
|
||||||
|
area: frontend
|
||||||
|
status: concept
|
||||||
|
progress: 0
|
||||||
|
position: [1280, 560]
|
||||||
|
|
||||||
|
- id: api-client
|
||||||
|
name: API 客户端层
|
||||||
|
area: frontend
|
||||||
|
status: concept
|
||||||
|
progress: 0
|
||||||
|
position: [1280, 720]
|
||||||
|
|
||||||
|
edges:
|
||||||
|
# 基础设施 → 共享层
|
||||||
|
- from: monorepo-setup
|
||||||
|
to: shared-ui
|
||||||
|
type: dependency
|
||||||
|
- from: monorepo-setup
|
||||||
|
to: shared-utils
|
||||||
|
type: dependency
|
||||||
|
- from: monorepo-setup
|
||||||
|
to: shared-hooks
|
||||||
|
type: dependency
|
||||||
|
- from: monorepo-setup
|
||||||
|
to: shared-types
|
||||||
|
type: dependency
|
||||||
|
- from: monorepo-setup
|
||||||
|
to: local-data-layer
|
||||||
|
type: dependency
|
||||||
|
- from: monorepo-setup
|
||||||
|
to: survey-app-shell
|
||||||
|
type: dependency
|
||||||
|
|
||||||
|
# 共享类型 → 其他共享层
|
||||||
|
- from: shared-types
|
||||||
|
to: shared-ui
|
||||||
|
type: dependency
|
||||||
|
- from: shared-types
|
||||||
|
to: shared-utils
|
||||||
|
type: dependency
|
||||||
|
- from: shared-types
|
||||||
|
to: api-client
|
||||||
|
type: dependency
|
||||||
|
|
||||||
|
# 数据层 → RN 应用
|
||||||
|
- from: local-data-layer
|
||||||
|
to: survey-app-shell
|
||||||
|
type: dependency
|
||||||
|
- from: local-data-layer
|
||||||
|
to: floor-map
|
||||||
|
type: dependency
|
||||||
|
- from: local-data-layer
|
||||||
|
to: item-form
|
||||||
|
type: dependency
|
||||||
|
- from: local-data-layer
|
||||||
|
to: photo-capture
|
||||||
|
type: dependency
|
||||||
|
- from: local-data-layer
|
||||||
|
to: inventory-summary
|
||||||
|
type: dependency
|
||||||
|
|
||||||
|
# RN 应用内部依赖
|
||||||
|
- from: survey-app-shell
|
||||||
|
to: floor-map
|
||||||
|
type: dependency
|
||||||
|
- from: survey-app-shell
|
||||||
|
to: inventory-summary
|
||||||
|
type: dependency
|
||||||
|
- from: floor-map
|
||||||
|
to: item-form
|
||||||
|
type: dependency
|
||||||
|
- from: item-form
|
||||||
|
to: photo-capture
|
||||||
|
type: dependency
|
||||||
|
|
||||||
|
# Web 前端(预留)
|
||||||
|
- from: monorepo-setup
|
||||||
|
to: app-scaffold
|
||||||
|
type: dependency
|
||||||
|
- from: shared-ui
|
||||||
|
to: app-scaffold
|
||||||
|
type: dependency
|
||||||
|
- from: app-scaffold
|
||||||
|
to: routing
|
||||||
|
type: dependency
|
||||||
|
- from: app-scaffold
|
||||||
|
to: theming
|
||||||
|
type: dependency
|
||||||
|
- from: app-scaffold
|
||||||
|
to: state-management
|
||||||
|
type: dependency
|
||||||
|
- from: app-scaffold
|
||||||
|
to: api-client
|
||||||
|
type: dependency
|
||||||
30
.blueprint/modules/api-client.md
Normal file
30
.blueprint/modules/api-client.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
id: api-client
|
||||||
|
name: API 客户端层
|
||||||
|
area: frontend
|
||||||
|
status: concept
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
封装后端 API 调用,包含统一鉴权、错误处理和接口类型定义。以 packages/api 形式跨 app 共享,或在各 app 内独立维护。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 💭 HTTP 客户端实例配置
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: packages/utils/src/request.ts, apps/app-one/src/api/client.ts
|
||||||
|
- acceptance: 配置 baseURL、超时时间,请求拦截器自动附加 Authorization header,响应拦截器统一处理 401/403/500 错误码
|
||||||
|
|
||||||
|
### 💭 API 接口类型化封装
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/app-one/src/api/types.ts, apps/app-one/src/api/auth.ts
|
||||||
|
- acceptance: 每个 API 模块导出类型安全的请求函数(入参和返回值均有 TS 类型),不使用 any
|
||||||
|
|
||||||
|
### 💭 数据请求缓存与 SWR 集成
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/app-one/src/api/hooks/useAuthQuery.ts
|
||||||
|
- acceptance: 基于 SWR 或 React Query 封装常用接口 hook,支持缓存、重试、乐观更新,避免重复请求
|
||||||
28
.blueprint/modules/app-scaffold.md
Normal file
28
.blueprint/modules/app-scaffold.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
id: app-scaffold
|
||||||
|
name: 应用脚手架模板
|
||||||
|
area: frontend
|
||||||
|
status: concept
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
新 app 的起始模板,包含 Vite 项目配置、HTML 入口、React 根组件、环境变量规范。monorepo 中每个 app 从此模板派生。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 💭 创建第一个 App(apps/app-one)
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/app-one/package.json, apps/app-one/vite.config.ts, apps/app-one/index.html, apps/app-one/src/main.tsx, apps/app-one/src/App.tsx
|
||||||
|
- acceptance: pnpm dev 能启动,pnpm build 产出 dist/,src/App.tsx 渲染 Hello World,正确引入 @repo/ui 和 @repo/utils
|
||||||
|
|
||||||
|
### 💭 移动端视口基础配置
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: apps/app-one/index.html, apps/app-one/src/styles/global.css
|
||||||
|
- acceptance: meta viewport 设置 initial-scale=1,禁用双击缩放,全局 CSS reset 适配移动端(100dvh、touch-action 等)
|
||||||
|
|
||||||
|
## 决策记录
|
||||||
|
|
||||||
|
- 每个 app 独立配置 Vite 而非共享一个构建进程:便于各 app 独立部署和差异化配置,构建缓存也可隔离
|
||||||
40
.blueprint/modules/floor-map.md
Normal file
40
.blueprint/modules/floor-map.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
id: floor-map
|
||||||
|
name: 楼层地图与标记点管理
|
||||||
|
area: rn-app
|
||||||
|
status: planned
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
以 SVG/Image 占位图为底图,支持长按添加标记点、点击标记点进入编辑的交互逻辑。标记点坐标以相对比例(0~1)存储,替换真实楼层图时无需修改数据。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 📋 平面图占位容器与坐标系
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/features/map/FloorMap.tsx
|
||||||
|
- depends: survey-app-shell
|
||||||
|
- acceptance: 渲染一个带灰色背景的矩形占位区域作为平面图,使用 onLayout 获取实际像素尺寸并转换相对坐标(0~1),容器宽高比固定为 4:3,适配折叠/展开两种宽度
|
||||||
|
|
||||||
|
### 📋 长按手势添加标记点
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/features/map/useMarkerGesture.ts
|
||||||
|
- depends: floor-map
|
||||||
|
- acceptance: 在平面图区域长按 500ms 后触发,将触点位置转换为相对坐标并调用 insertMarker 写入数据库,新标记点立即在地图上显示,不误触短按事件
|
||||||
|
|
||||||
|
### 📋 标记点图标组件
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/features/map/MapMarker.tsx
|
||||||
|
- depends: floor-map
|
||||||
|
- acceptance: 在平面图上按相对坐标绝对定位渲染图钉图标,已有物品的标记点显示蓝色图钉 + 物品数量角标,空标记点显示灰色图钉,点击触发 onPress 回调
|
||||||
|
|
||||||
|
### 📋 当前楼层标记点数据加载
|
||||||
|
- status: todo
|
||||||
|
- complexity: S
|
||||||
|
- files: apps/property-survey/src/features/map/MarkerList.tsx
|
||||||
|
- depends: floor-map
|
||||||
|
- acceptance: 楼层切换时调用 getMarkersByFloor 重新查询,渲染该楼层所有 MapMarker,删除标记点时弹出确认对话框(含级联删除提示)
|
||||||
40
.blueprint/modules/inventory-summary.md
Normal file
40
.blueprint/modules/inventory-summary.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
id: inventory-summary
|
||||||
|
name: 汇总列表与统计
|
||||||
|
area: rn-app
|
||||||
|
status: planned
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
汇总展示全部已登记物品,支持按楼层和物品名筛选,底部显示总件数和总金额统计。提供 CSV 导出通过系统分享面板发送备份。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 📋 汇总数据查询 Hook
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/features/summary/useSummaryData.ts
|
||||||
|
- depends: local-data-layer
|
||||||
|
- acceptance: 查询所有 items JOIN markers JOIN photos,返回带楼层、坐标、物品名、数量、单价、备注、照片数的扁平列表;支持按 floor(1/2/3/全部)和 name 关键字过滤;数据写入后调用 refresh() 触发重新查询
|
||||||
|
|
||||||
|
### 📋 汇总列表与筛选栏
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/features/summary/SummaryList.tsx, apps/property-survey/src/features/summary/FilterBar.tsx
|
||||||
|
- depends: inventory-summary
|
||||||
|
- acceptance: 列表每行显示楼层标签、物品名、数量、单价、备注1;FilterBar 提供楼层选择器(1F/2F/3F/全部)和物品名搜索框;滚动性能流畅(FlatList),空数据时显示引导文案
|
||||||
|
|
||||||
|
### 📋 统计汇总卡片
|
||||||
|
- status: todo
|
||||||
|
- complexity: S
|
||||||
|
- files: apps/property-survey/src/features/summary/SummaryStats.tsx
|
||||||
|
- depends: inventory-summary
|
||||||
|
- acceptance: 固定在列表顶部,展示:登记点总数、物品种类数、总数量合计、总金额合计(数量×单价求和,单价为空则不计入),数值随筛选条件实时更新
|
||||||
|
|
||||||
|
### 📋 CSV 导出与系统分享
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/features/summary/exportData.ts
|
||||||
|
- depends: inventory-summary
|
||||||
|
- acceptance: 点击导出按钮,将当前筛选结果生成 UTF-8 BOM 的 CSV 文件(含表头:楼层/标记点名/物品名/数量/单价/备注1/备注2/照片数),写入临时目录后调用 expo-sharing 弹出系统分享面板,可发送到微信/邮件/云盘
|
||||||
33
.blueprint/modules/item-form.md
Normal file
33
.blueprint/modules/item-form.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
id: item-form
|
||||||
|
name: 物品登记表单
|
||||||
|
area: rn-app
|
||||||
|
status: planned
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
点击地图标记点后弹出的物品编辑面板。折叠时以底部抽屉形式展现,展开时在右侧栏内联显示。支持单个标记点下的多条物品记录增删改。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 📋 底部抽屉/右栏容器
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/features/item/ItemFormSheet.tsx
|
||||||
|
- depends: survey-app-shell, floor-map
|
||||||
|
- acceptance: 折叠时从屏幕底部滑出(BottomSheet),展开时在 FoldableLayout 右栏内渲染;接受 markerId 和 onClose 两个 prop;顶部显示标记点位置名称和所属楼层
|
||||||
|
|
||||||
|
### 📋 物品字段表单
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/features/item/ItemFields.tsx, apps/property-survey/src/features/item/useItemForm.ts
|
||||||
|
- depends: item-form
|
||||||
|
- acceptance: 包含物品名称(必填文本)、数量(数字键盘)、单价(数字键盘,可选)、备注1(多行文本)、备注2(多行文本)五个字段;保存时校验物品名称非空;useItemForm 管理字段状态和 insertItem / updateItem 调用
|
||||||
|
|
||||||
|
### 📋 标记点下物品列表
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/features/item/ItemList.tsx
|
||||||
|
- depends: item-form
|
||||||
|
- acceptance: 在表单上方列出当前标记点的所有物品(物品名 + 数量 + 单价),点击条目进入编辑,左滑显示删除按钮,点击「+新增物品」清空表单进入新增模式
|
||||||
39
.blueprint/modules/local-data-layer.md
Normal file
39
.blueprint/modules/local-data-layer.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
id: local-data-layer
|
||||||
|
name: 本地数据持久化层
|
||||||
|
area: data
|
||||||
|
status: planned
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
基于 Expo SQLite 的本地数据库层,管理标记点、物品记录和照片路径三张核心表。所有写操作使用事务保证原子性,供上层功能模块调用。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 📋 SQLite 初始化与 Schema 建表
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/db/database.ts, apps/property-survey/src/db/schema.ts
|
||||||
|
- acceptance: App 启动时自动执行 CREATE TABLE IF NOT EXISTS,建立 markers / items / photos 三张表,重复启动不报错,字段与设计文档一致
|
||||||
|
|
||||||
|
### 📋 标记点 CRUD 操作
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/db/markers.ts
|
||||||
|
- depends: local-data-layer
|
||||||
|
- acceptance: 提供 insertMarker / getMarkersByFloor / updateMarker / deleteMarker 四个函数,deleteMarker 级联删除关联 items 和 photos,所有函数返回类型安全的 Promise
|
||||||
|
|
||||||
|
### 📋 物品记录 CRUD 操作
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/db/items.ts
|
||||||
|
- depends: local-data-layer
|
||||||
|
- acceptance: 提供 insertItem / getItemsByMarker / updateItem / deleteItem 四个函数,支持批量查询(传入 marker_id 数组),返回带关联照片数量的扩展类型
|
||||||
|
|
||||||
|
### 📋 照片路径 CRUD 操作
|
||||||
|
- status: todo
|
||||||
|
- complexity: S
|
||||||
|
- files: apps/property-survey/src/db/photos.ts
|
||||||
|
- depends: local-data-layer
|
||||||
|
- acceptance: 提供 insertPhoto / getPhotosByItem / deletePhoto / reorderPhotos 四个函数,deletePhoto 同步删除设备文件系统中的对应图片文件
|
||||||
40
.blueprint/modules/monorepo-setup.md
Normal file
40
.blueprint/modules/monorepo-setup.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
id: monorepo-setup
|
||||||
|
name: Monorepo 工程配置
|
||||||
|
area: infrastructure
|
||||||
|
status: done
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
pnpm workspace 单体仓库基础配置,涵盖包管理、构建脚本和 Node.js 引擎约束。所有 apps/* 和 packages/* 自动纳入 workspace。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### ✅ 初始化 pnpm workspace
|
||||||
|
- status: done
|
||||||
|
- complexity: S
|
||||||
|
- files: package.json, pnpm-workspace.yaml
|
||||||
|
- acceptance: pnpm-workspace.yaml 正确声明 apps/* 和 packages/*,根 package.json 包含 dev/build/lint 脚本,engines 约束 node>=18 pnpm>=8
|
||||||
|
|
||||||
|
### 💭 统一 TypeScript 基础配置
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: tsconfig.base.json
|
||||||
|
- acceptance: 根目录提供 tsconfig.base.json,各子包通过 extends 继承,启用 strict 模式
|
||||||
|
|
||||||
|
### 💭 统一 ESLint / Prettier 配置
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: eslint.config.js, .prettierrc
|
||||||
|
- acceptance: 根目录提供共享 lint 规则,各子包可通过 overrides 扩展,pnpm lint 从根目录一键运行
|
||||||
|
|
||||||
|
### 💭 构建工具链选型
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: packages/build-config/package.json, packages/build-config/vite.base.ts
|
||||||
|
- acceptance: 封装 Vite 基础配置到 packages/build-config,各 app 通过 extends 引入,减少重复配置
|
||||||
|
|
||||||
|
## 决策记录
|
||||||
|
|
||||||
|
- 选择 pnpm workspace 而非 Turborepo/Nx:初期项目规模小,pnpm 原生 workspace 足够,避免引入额外工具链复杂度
|
||||||
26
.blueprint/modules/photo-capture.md
Normal file
26
.blueprint/modules/photo-capture.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
id: photo-capture
|
||||||
|
name: 照片采集与管理
|
||||||
|
area: rn-app
|
||||||
|
status: planned
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
调用设备摄像头或相册为物品条目添加多张照片,照片压缩后存储到 App 专属目录,路径写入 SQLite photos 表。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 📋 摄像头调用与图片压缩
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/features/photo/usePhotoCapture.ts
|
||||||
|
- depends: local-data-layer
|
||||||
|
- acceptance: 使用 expo-image-picker 提供「拍照」和「从相册选择」两种入口;拍摄/选择后自动压缩至最大宽度 1080px、JPEG quality 0.75;将压缩后的文件复制到 expo-file-system 的 App 专属目录;调用 insertPhoto 写入数据库;全流程有权限检查,拒绝权限时给出提示
|
||||||
|
|
||||||
|
### 📋 照片网格预览与删除
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/features/photo/PhotoGrid.tsx, apps/property-survey/src/features/photo/PhotoPicker.tsx
|
||||||
|
- depends: photo-capture
|
||||||
|
- acceptance: 以 3 列网格展示已添加的照片缩略图;点击照片全屏预览(支持左右滑动切换);长按照片显示「删除」确认弹窗,删除时同步调用 deletePhoto(含文件系统删除);末尾显示「+」按钮触发 PhotoPicker 添加更多
|
||||||
30
.blueprint/modules/routing.md
Normal file
30
.blueprint/modules/routing.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
id: routing
|
||||||
|
name: 路由与页面结构
|
||||||
|
area: frontend
|
||||||
|
status: concept
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
基于 React Router 的单页应用路由体系,含懒加载、受保护路由和移动端页面切换动画。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 💭 路由基础配置
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/app-one/src/router/index.tsx, apps/app-one/src/router/routes.ts
|
||||||
|
- acceptance: 使用 react-router-dom v6 createBrowserRouter,配置首页和 404 页,支持代码分割(lazy + Suspense)
|
||||||
|
|
||||||
|
### 💭 受保护路由(需登录)
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/app-one/src/router/ProtectedRoute.tsx
|
||||||
|
- acceptance: 未登录访问受保护路由自动跳转登录页,登录后重定向回原目标页,支持角色权限扩展
|
||||||
|
|
||||||
|
### 💭 移动端页面切换动画
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/app-one/src/router/PageTransition.tsx
|
||||||
|
- acceptance: 路由切换时有 slide-in/slide-out 动画,与浏览器前进/后退方向一致,不影响首屏性能
|
||||||
36
.blueprint/modules/shared-hooks.md
Normal file
36
.blueprint/modules/shared-hooks.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
id: shared-hooks
|
||||||
|
name: 共享 React Hooks
|
||||||
|
area: shared
|
||||||
|
status: concept
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
跨 app 复用的 React 自定义 Hooks,以 packages/hooks 形式发布。依赖 React,不依赖具体 UI 框架。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 💭 搭建 hooks 库骨架
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: packages/hooks/package.json, packages/hooks/src/index.ts
|
||||||
|
- acceptance: packages/hooks 可被 workspace 内任意 React 应用通过 @repo/hooks 引入,peer dependency 声明 react
|
||||||
|
|
||||||
|
### 💭 数据请求 Hook(useRequest)
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: packages/hooks/src/useRequest.ts
|
||||||
|
- acceptance: 支持 loading/data/error 三态,支持手动触发和依赖自动触发,支持取消请求(AbortController)
|
||||||
|
|
||||||
|
### 💭 移动端交互 Hooks
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: packages/hooks/src/useTouch.ts, packages/hooks/src/useScrollLock.ts, packages/hooks/src/useVirtualKeyboard.ts
|
||||||
|
- acceptance: useTouch 处理 swipe 手势,useScrollLock 控制 body 滚动,useVirtualKeyboard 检测键盘弹出并调整视口
|
||||||
|
|
||||||
|
### 💭 持久化状态 Hook(useLocalStorage)
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: packages/hooks/src/useLocalStorage.ts
|
||||||
|
- acceptance: 封装 useState + localStorage 同步,支持 SSR 安全(无 window 时优雅降级),TypeScript 泛型
|
||||||
30
.blueprint/modules/shared-types.md
Normal file
30
.blueprint/modules/shared-types.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
id: shared-types
|
||||||
|
name: 共享类型定义
|
||||||
|
area: shared
|
||||||
|
status: concept
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
跨 app 和 packages 共享的 TypeScript 类型定义,以 packages/types 形式发布。纯类型文件,无运行时代码。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 💭 搭建类型包骨架
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: packages/types/package.json, packages/types/src/index.ts
|
||||||
|
- acceptance: packages/types 仅包含 .d.ts 或 type-only TS 文件,被引入时不产生任何运行时代码
|
||||||
|
|
||||||
|
### 💭 通用业务类型
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: packages/types/src/common.ts
|
||||||
|
- acceptance: 定义 ApiResponse<T>、PaginatedResult<T>、Nullable<T> 等通用泛型类型,供所有 app 和 packages 使用
|
||||||
|
|
||||||
|
### 💭 环境与配置类型
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: packages/types/src/env.d.ts
|
||||||
|
- acceptance: 声明 import.meta.env 类型扩展,各 app 的环境变量在 IDE 中有类型提示
|
||||||
36
.blueprint/modules/shared-ui.md
Normal file
36
.blueprint/modules/shared-ui.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
id: shared-ui
|
||||||
|
name: 共享 UI 组件库
|
||||||
|
area: shared
|
||||||
|
status: concept
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
跨 app 复用的 React UI 组件集合,以 packages/ui 形式发布到 workspace 内部。面向移动端适配(触摸友好、响应式)。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 💭 搭建组件库骨架
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: packages/ui/package.json, packages/ui/src/index.ts, packages/ui/vite.config.ts
|
||||||
|
- acceptance: packages/ui 可被 apps/* 通过 workspace:* 引入,支持 tree-shaking,导出类型声明文件
|
||||||
|
|
||||||
|
### 💭 基础原子组件
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: packages/ui/src/components/Button.tsx, packages/ui/src/components/Input.tsx, packages/ui/src/components/Card.tsx
|
||||||
|
- acceptance: Button/Input/Card 组件覆盖常用变体,props 类型完整,支持 className 扩展
|
||||||
|
|
||||||
|
### 💭 移动端导航组件
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: packages/ui/src/components/BottomNav.tsx, packages/ui/src/components/TopBar.tsx
|
||||||
|
- acceptance: BottomNav 支持图标+文字标签,TopBar 支持返回按钮和标题插槽,两者均适配 safe-area-inset
|
||||||
|
|
||||||
|
### 💭 反馈类组件(Toast / Modal / Loading)
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: packages/ui/src/components/Toast.tsx, packages/ui/src/components/Modal.tsx, packages/ui/src/components/Loading.tsx
|
||||||
|
- acceptance: Toast 支持 success/error/info 三种类型,Modal 支持受控和非受控,Loading 可全屏覆盖
|
||||||
36
.blueprint/modules/shared-utils.md
Normal file
36
.blueprint/modules/shared-utils.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
id: shared-utils
|
||||||
|
name: 共享工具函数库
|
||||||
|
area: shared
|
||||||
|
status: concept
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
跨 app 复用的纯函数工具集,以 packages/utils 形式发布到 workspace 内部。不依赖 React,可在任何环境使用。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 💭 搭建工具库骨架
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: packages/utils/package.json, packages/utils/src/index.ts
|
||||||
|
- acceptance: packages/utils 可被 workspace 内任意包通过 @repo/utils 引入,导出类型声明文件
|
||||||
|
|
||||||
|
### 💭 格式化工具集
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: packages/utils/src/format.ts
|
||||||
|
- acceptance: 提供日期格式化、数字格式化(货币/百分比)、手机号脱敏等常用函数,每个函数有单元测试
|
||||||
|
|
||||||
|
### 💭 本地存储工具
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: packages/utils/src/storage.ts
|
||||||
|
- acceptance: 封装 localStorage/sessionStorage,支持 JSON 序列化和过期时间,TypeScript 泛型推导
|
||||||
|
|
||||||
|
### 💭 HTTP 请求工具
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: packages/utils/src/request.ts
|
||||||
|
- acceptance: 基于 fetch 封装,支持请求/响应拦截器、统一错误处理、超时控制,返回类型安全的 Promise
|
||||||
28
.blueprint/modules/state-management.md
Normal file
28
.blueprint/modules/state-management.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
id: state-management
|
||||||
|
name: 全局状态管理
|
||||||
|
area: frontend
|
||||||
|
status: concept
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
跨组件的全局状态方案,覆盖用户会话、UI 状态等场景。轻量优先(Zustand),避免过度设计。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 💭 用户会话 Store
|
||||||
|
- status: concept
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/app-one/src/stores/authStore.ts
|
||||||
|
- acceptance: 使用 Zustand 管理 user/token/isLoggedIn,提供 login/logout action,token 持久化到 localStorage
|
||||||
|
|
||||||
|
### 💭 全局 UI 状态 Store
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: apps/app-one/src/stores/uiStore.ts
|
||||||
|
- acceptance: 管理全局 loading、toast 消息队列、modal 开关状态,与 packages/ui 的反馈组件联动
|
||||||
|
|
||||||
|
## 决策记录
|
||||||
|
|
||||||
|
- 选择 Zustand 而非 Redux:移动端场景状态相对简单,Zustand API 更轻量,无需 boilerplate,TypeScript 支持良好
|
||||||
39
.blueprint/modules/survey-app-shell.md
Normal file
39
.blueprint/modules/survey-app-shell.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
id: survey-app-shell
|
||||||
|
name: 应用外壳与折叠屏布局
|
||||||
|
area: rn-app
|
||||||
|
status: planned
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
React Native (Expo SDK 52 + Expo Router) 应用骨架,实现 Z Fold 6 折叠/展开双形态布局切换。折叠时单栏显示,展开时左侧地图 + 右侧表单双栏并排。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 📋 Expo 应用骨架初始化
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/app.json, apps/property-survey/package.json, apps/property-survey/app/_layout.tsx, apps/property-survey/app/index.tsx, apps/property-survey/app/summary.tsx
|
||||||
|
- depends: local-data-layer
|
||||||
|
- acceptance: `pnpm --filter property-survey start` 能在 Expo Go 或开发构建中启动,底部导航可在「登记」和「汇总」两个页面间切换,SQLite 数据库在启动时完成初始化
|
||||||
|
|
||||||
|
### 📋 折叠屏状态感知 Hook
|
||||||
|
- status: todo
|
||||||
|
- complexity: S
|
||||||
|
- files: apps/property-survey/src/layout/useFoldState.ts
|
||||||
|
- acceptance: useFoldState 返回 `{ isUnfolded: boolean, windowWidth: number }`,以 720px 为断点区分折叠/展开状态,useWindowDimensions 变化时自动更新,在模拟器宽度调整时可观察到状态切换
|
||||||
|
|
||||||
|
### 📋 双栏/单栏自适应布局容器
|
||||||
|
- status: todo
|
||||||
|
- complexity: M
|
||||||
|
- files: apps/property-survey/src/layout/FoldableLayout.tsx
|
||||||
|
- depends: survey-app-shell
|
||||||
|
- acceptance: 展开时渲染左右两栏(左侧 flexGrow:1 地图区,右侧 380px 详情区),折叠时只渲染左侧(地图全屏),接受 `left` 和 `right` 两个 ReactNode 插槽
|
||||||
|
|
||||||
|
### 📋 楼层切换标签组件
|
||||||
|
- status: todo
|
||||||
|
- complexity: S
|
||||||
|
- files: apps/property-survey/src/layout/FloorTabs.tsx
|
||||||
|
- depends: survey-app-shell
|
||||||
|
- acceptance: 显示 1F / 2F / 3F 三个标签,选中项高亮,onChange 回调传出当前楼层数字(1/2/3),组件宽度自适应容器
|
||||||
30
.blueprint/modules/theming.md
Normal file
30
.blueprint/modules/theming.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
id: theming
|
||||||
|
name: 主题与样式系统
|
||||||
|
area: frontend
|
||||||
|
status: concept
|
||||||
|
---
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
基于 CSS 变量的主题系统,支持亮色/暗色模式切换,结合 Tailwind CSS 或 CSS Modules 实现统一的视觉风格。
|
||||||
|
|
||||||
|
## 任务卡
|
||||||
|
|
||||||
|
### 💭 设计 Token 与 CSS 变量
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: packages/ui/src/styles/tokens.css
|
||||||
|
- acceptance: 定义颜色、间距、字体、圆角等设计 token 为 CSS 变量,dark 模式通过 prefers-color-scheme 或 [data-theme] 切换
|
||||||
|
|
||||||
|
### 💭 主题切换逻辑
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: apps/app-one/src/hooks/useTheme.ts
|
||||||
|
- acceptance: 提供 useTheme hook,支持手动切换和跟随系统,偏好持久化到 localStorage
|
||||||
|
|
||||||
|
### 💭 Tailwind 配置集成
|
||||||
|
- status: concept
|
||||||
|
- complexity: S
|
||||||
|
- files: packages/build-config/tailwind.base.ts, apps/app-one/tailwind.config.ts
|
||||||
|
- acceptance: 共享 Tailwind 配置,设计 token 与 Tailwind 主题颜色/间距对齐,各 app 可扩展
|
||||||
28
.blueprint/usage.json
Normal file
28
.blueprint/usage.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"project_name": "react-phone-apps",
|
||||||
|
"snapshots": [
|
||||||
|
{
|
||||||
|
"at": "2026-04-07T06:17:15Z",
|
||||||
|
"blocked_reasons": [],
|
||||||
|
"conventions_version": "unknown",
|
||||||
|
"iteration": 1,
|
||||||
|
"modules": {
|
||||||
|
"blocked": 0,
|
||||||
|
"concept": 9,
|
||||||
|
"done": 1,
|
||||||
|
"in_progress": 0,
|
||||||
|
"planned": 0,
|
||||||
|
"stalled": [],
|
||||||
|
"total": 10
|
||||||
|
},
|
||||||
|
"tasks": {
|
||||||
|
"blocked": 0,
|
||||||
|
"dispatched": 0,
|
||||||
|
"done": 1,
|
||||||
|
"in_progress": 0,
|
||||||
|
"todo": 0,
|
||||||
|
"total": 32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
8
.claude/settings.json
Normal file
8
.claude/settings.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"lian-jing:group-da6dc719": {
|
||||||
|
"type": "http",
|
||||||
|
"url": "http://localhost:27190/mcp/group/da6dc719"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
.codemap/main-panel.json
Normal file
1
.codemap/main-panel.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
.next/
|
||||||
|
*.log
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# Windows 保留设备名(误创建的空文件)
|
||||||
|
/nul
|
||||||
2
.npmrc
Normal file
2
.npmrc
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
strict-peer-dependencies=false
|
||||||
|
auto-install-peers=true
|
||||||
0
apps/.gitkeep
Normal file
0
apps/.gitkeep
Normal file
134
fix-scoop-git.ps1
Normal file
134
fix-scoop-git.ps1
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
Write-Host "修复 Scoop 和 Git 安装..."
|
||||||
|
|
||||||
|
$scoopDir = "E:\Scoop"
|
||||||
|
$appsDir = "$scoopDir\apps"
|
||||||
|
$shimsDir = "$scoopDir\shims"
|
||||||
|
|
||||||
|
# 1. 修复 7zip shim
|
||||||
|
Write-Host "1. 修复 7zip shim..."
|
||||||
|
$7zShim = "$shimsDir\7z.shim"
|
||||||
|
$7zPath = "$appsDir\7zip\25.01\7z.exe"
|
||||||
|
if (Test-Path $7zPath) {
|
||||||
|
if (Test-Path $7zShim) {
|
||||||
|
Set-Content $7zShim "path = `"$7zPath`""
|
||||||
|
Write-Host " 更新 7z.shim 指向: $7zPath"
|
||||||
|
} else {
|
||||||
|
Write-Host " 错误: 7z.shim 不存在"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host " 错误: 7z.exe 未找到,请先安装 7-zip: scoop install 7zip"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. 修复 7zip current 符号链接
|
||||||
|
Write-Host "2. 修复 7zip current 符号链接..."
|
||||||
|
$7zipCurrent = "$appsDir\7zip\current"
|
||||||
|
if (-not (Test-Path $7zipCurrent)) {
|
||||||
|
cmd /c mklink /J "$7zipCurrent" "$appsDir\7zip\25.01" 2>$null
|
||||||
|
if (Test-Path $7zipCurrent) {
|
||||||
|
Write-Host " 创建 current 符号链接"
|
||||||
|
} else {
|
||||||
|
Write-Host " 警告: 无法创建符号链接,使用绝对路径"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host " current 符号链接已存在"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 3. 手动提取 Git
|
||||||
|
Write-Host "3. 手动提取 Git..."
|
||||||
|
$gitDir = "$appsDir\git\2.53.0.2"
|
||||||
|
$dl7z = "$gitDir\dl.7z"
|
||||||
|
if (Test-Path $dl7z) {
|
||||||
|
Write-Host " 找到 dl.7z: $dl7z"
|
||||||
|
|
||||||
|
# 创建目标目录
|
||||||
|
if (-not (Test-Path $gitDir)) {
|
||||||
|
New-Item -ItemType Directory -Path $gitDir -Force | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# 使用 7z 提取
|
||||||
|
Write-Host " 正在提取文件..."
|
||||||
|
& $7zPath x "-o$gitDir" "-y" "$dl7z" | Out-Null
|
||||||
|
|
||||||
|
if (Test-Path "$gitDir\bin\git.exe") {
|
||||||
|
Write-Host " 提取成功: git.exe 已存在"
|
||||||
|
} else {
|
||||||
|
Write-Host " 警告: 提取可能失败,检查目录内容"
|
||||||
|
Get-ChildItem $gitDir -Recurse -File | Select-Object -First 10 | ForEach-Object { Write-Host " $_" }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host " 错误: dl.7z 未找到,请重新下载"
|
||||||
|
Write-Host " 运行: scoop cache rm git; scoop download git"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 4. 创建 Git shims
|
||||||
|
Write-Host "4. 创建 Git shims..."
|
||||||
|
|
||||||
|
# git shim
|
||||||
|
$gitShim = "$shimsDir\git.shim"
|
||||||
|
$gitExe = "$gitDir\bin\git.exe"
|
||||||
|
if (Test-Path $gitExe) {
|
||||||
|
Set-Content $gitShim "path = `"$gitExe`""
|
||||||
|
Write-Host " 创建 git.shim"
|
||||||
|
|
||||||
|
# 复制 shim 可执行文件
|
||||||
|
$shimExe = "$shimsDir\git.exe"
|
||||||
|
if (-not (Test-Path $shimExe)) {
|
||||||
|
Copy-Item "$shimsDir\7z.exe" $shimExe -ErrorAction SilentlyContinue
|
||||||
|
if (Test-Path $shimExe) {
|
||||||
|
Write-Host " 创建 git.exe shim"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host " 错误: git.exe 未找到"
|
||||||
|
}
|
||||||
|
|
||||||
|
# sh (bash) shim
|
||||||
|
$shShim = "$shimsDir\sh.shim"
|
||||||
|
$shExe = "$gitDir\bin\sh.exe"
|
||||||
|
if (Test-Path $shExe) {
|
||||||
|
Set-Content $shShim "path = `"$shExe`""
|
||||||
|
Write-Host " 创建 sh.shim"
|
||||||
|
} else {
|
||||||
|
Write-Host " 警告: sh.exe 未找到"
|
||||||
|
}
|
||||||
|
|
||||||
|
# git-bash shim
|
||||||
|
$gitBashShim = "$shimsDir\git-bash.shim"
|
||||||
|
$gitBashExe = "$gitDir\git-bash.exe"
|
||||||
|
if (Test-Path $gitBashExe) {
|
||||||
|
Set-Content $gitBashShim "path = `"$gitBashExe`""
|
||||||
|
Write-Host " 创建 git-bash.shim"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 5. 更新 PATH 并测试
|
||||||
|
Write-Host "5. 测试安装..."
|
||||||
|
$env:Path = "$shimsDir;$env:Path"
|
||||||
|
|
||||||
|
Write-Host "`n测试命令:"
|
||||||
|
try {
|
||||||
|
$gitVersion = git --version 2>$null
|
||||||
|
if ($gitVersion) {
|
||||||
|
Write-Host " ✓ git: $gitVersion"
|
||||||
|
} else {
|
||||||
|
Write-Host " ✗ git: 命令失败"
|
||||||
|
Write-Host " 临时使用: $gitExe"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host " ✗ git: 错误: $_"
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$7zVersion = 7z --help 2>$null | Select-Object -First 1
|
||||||
|
if ($7zVersion) {
|
||||||
|
Write-Host " ✓ 7z: 可用"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host " ✗ 7z: 错误"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`n修复完成!"
|
||||||
|
Write-Host "如果命令仍然不可用,请重启终端或运行:"
|
||||||
|
Write-Host " `$env:Path = `"$shimsDir;`$env:Path`""
|
||||||
|
Write-Host "`n然后测试: git --version"
|
||||||
69
fix-scoop.ps1
Normal file
69
fix-scoop.ps1
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
Write-Host "Fixing Scoop shims for git..."
|
||||||
|
|
||||||
|
$scoopDir = "E:\Scoop"
|
||||||
|
$gitDir = "E:\Scoop\apps\git\2.53.0"
|
||||||
|
$shimsDir = "E:\Scoop\shims"
|
||||||
|
|
||||||
|
Write-Host "1. Checking git installation..."
|
||||||
|
if (-not (Test-Path "$gitDir\bin\git.exe")) {
|
||||||
|
Write-Host "ERROR: git.exe not found at $gitDir\bin\git.exe"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
Write-Host " git.exe found"
|
||||||
|
|
||||||
|
Write-Host "2. Fixing sh.shim..."
|
||||||
|
$shShim = "$shimsDir\sh.shim"
|
||||||
|
if (Test-Path $shShim) {
|
||||||
|
$content = Get-Content $shShim
|
||||||
|
if ($content -match "current") {
|
||||||
|
Set-Content $shShim 'path = "E:\Scoop\apps\git\2.53.0\bin\sh.exe"'
|
||||||
|
Write-Host " Updated sh.shim to use absolute path"
|
||||||
|
} else {
|
||||||
|
Write-Host " sh.shim already uses absolute path"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host " ERROR: sh.shim not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "3. Creating git shim..."
|
||||||
|
$gitShim = "$shimsDir\git.shim"
|
||||||
|
if (-not (Test-Path $gitShim)) {
|
||||||
|
Set-Content $gitShim 'path = "E:\Scoop\apps\git\2.53.0\bin\git.exe"'
|
||||||
|
Write-Host " Created git.shim"
|
||||||
|
} else {
|
||||||
|
Write-Host " git.shim already exists"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "4. Creating git.exe shim executable..."
|
||||||
|
$gitExe = "$shimsDir\git.exe"
|
||||||
|
if (-not (Test-Path $gitExe)) {
|
||||||
|
$sourceShim = "$shimsDir\7z.exe"
|
||||||
|
if (Test-Path $sourceShim) {
|
||||||
|
Copy-Item $sourceShim $gitExe
|
||||||
|
Write-Host " Copied 7z.exe to git.exe"
|
||||||
|
} else {
|
||||||
|
Write-Host " ERROR: No source shim executable found"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host " git.exe already exists"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "5. Testing git command..."
|
||||||
|
$env:Path = "$shimsDir;$env:Path"
|
||||||
|
try {
|
||||||
|
git --version
|
||||||
|
Write-Host " SUCCESS: git command works!"
|
||||||
|
} catch {
|
||||||
|
Write-Host " WARNING: git command may not work directly, but you can use full path: $gitDir\bin\git.exe"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "6. Testing sh command..."
|
||||||
|
try {
|
||||||
|
sh --version
|
||||||
|
Write-Host " SUCCESS: sh command works!"
|
||||||
|
} catch {
|
||||||
|
Write-Host " WARNING: sh command may not work"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nFix complete. If commands still don't work, try restarting your terminal or running:"
|
||||||
|
Write-Host " . `$env:Path = `"E:\Scoop\shims;`$env:Path`""
|
||||||
49
init-git.ps1
Normal file
49
init-git.ps1
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
Write-Host "初始化 Git 仓库..."
|
||||||
|
|
||||||
|
# 检查是否已经是 Git 仓库
|
||||||
|
if (Test-Path .git) {
|
||||||
|
Write-Host "✓ 已经是 Git 仓库"
|
||||||
|
git status
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 初始化 Git
|
||||||
|
Write-Host "初始化 Git 仓库..."
|
||||||
|
git init
|
||||||
|
|
||||||
|
# 配置用户信息(如果未设置)
|
||||||
|
$gitUser = git config --global user.name
|
||||||
|
$gitEmail = git config --global user.email
|
||||||
|
|
||||||
|
if (-not $gitUser) {
|
||||||
|
Write-Host "提示: 请设置 Git 用户信息:"
|
||||||
|
Write-Host " git config --global user.name 'Your Name'"
|
||||||
|
Write-Host " git config --global user.email 'your.email@example.com'"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 添加文件
|
||||||
|
Write-Host "添加文件到暂存区..."
|
||||||
|
git add .
|
||||||
|
|
||||||
|
# 检查是否有文件被添加
|
||||||
|
$staged = git status --porcelain
|
||||||
|
if (-not $staged) {
|
||||||
|
Write-Host "警告: 没有文件被添加到暂存区,可能是 .gitignore 过滤了所有文件"
|
||||||
|
Write-Host "查看当前状态:"
|
||||||
|
git status
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 创建初始提交
|
||||||
|
Write-Host "创建初始提交..."
|
||||||
|
git commit -m "Initial commit: React phone apps project"
|
||||||
|
|
||||||
|
Write-Host "`n✓ Git 仓库初始化完成!"
|
||||||
|
Write-Host "当前分支: $(git branch --show-current)"
|
||||||
|
Write-Host "提交记录:"
|
||||||
|
git log --oneline -3
|
||||||
|
|
||||||
|
Write-Host "`n下一步:"
|
||||||
|
Write-Host "1. 连接到远程仓库: git remote add origin <repository-url>"
|
||||||
|
Write-Host "2. 推送到远程: git push -u origin main"
|
||||||
|
Write-Host "3. 查看状态: git status"
|
||||||
13
package.json
Normal file
13
package.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "react-phone-apps",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "pnpm -r --filter './apps/**' dev",
|
||||||
|
"build": "pnpm -r --filter './apps/**' build",
|
||||||
|
"lint": "pnpm -r lint"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18",
|
||||||
|
"pnpm": ">=8"
|
||||||
|
}
|
||||||
|
}
|
||||||
0
packages/.gitkeep
Normal file
0
packages/.gitkeep
Normal file
9
pnpm-lock.yaml
generated
Normal file
9
pnpm-lock.yaml
generated
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
lockfileVersion: '9.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
|
importers:
|
||||||
|
|
||||||
|
.: {}
|
||||||
3
pnpm-workspace.yaml
Normal file
3
pnpm-workspace.yaml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
packages:
|
||||||
|
- 'apps/*'
|
||||||
|
- 'packages/*'
|
||||||
35
test.ps1
Normal file
35
test.ps1
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
Write-Host "Testing git installation..."
|
||||||
|
$gitPath = "E:\Scoop\apps\git\2.53.0\bin\git.exe"
|
||||||
|
if (Test-Path $gitPath) {
|
||||||
|
Write-Host "Git executable exists at: $gitPath"
|
||||||
|
& $gitPath --version
|
||||||
|
} else {
|
||||||
|
Write-Host "Git executable not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nChecking current symlink..."
|
||||||
|
$currentLink = "E:\Scoop\apps\git\current"
|
||||||
|
if (Test-Path $currentLink) {
|
||||||
|
Write-Host "Current link exists"
|
||||||
|
$target = Get-Item $currentLink | Select-Object -ExpandProperty Target
|
||||||
|
Write-Host "Current link target: $target"
|
||||||
|
} else {
|
||||||
|
Write-Host "Current link does not exist"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nChecking sh.exe..."
|
||||||
|
$shPath = "E:\Scoop\apps\git\current\bin\sh.exe"
|
||||||
|
if (Test-Path $shPath) {
|
||||||
|
Write-Host "sh.exe exists at: $shPath"
|
||||||
|
} else {
|
||||||
|
Write-Host "sh.exe not found at: $shPath"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "`nChecking shim..."
|
||||||
|
$shimPath = "E:\Scoop\shims\sh.shim"
|
||||||
|
if (Test-Path $shimPath) {
|
||||||
|
Write-Host "sh.shim exists"
|
||||||
|
Get-Content $shimPath
|
||||||
|
} else {
|
||||||
|
Write-Host "sh.shim not found"
|
||||||
|
}
|
||||||
61
修复Git安装步骤.txt
Normal file
61
修复Git安装步骤.txt
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
修复 Scoop Git 安装步骤
|
||||||
|
|
||||||
|
请在新终端(CMD 或 PowerShell)中逐条执行以下命令:
|
||||||
|
|
||||||
|
1. 检查并修复 7zip shim
|
||||||
|
打开文件 E:\Scoop\shims\7z.shim,确保内容为:
|
||||||
|
path = "E:\Scoop\apps\7zip\25.01\7z.exe"
|
||||||
|
|
||||||
|
如果不同,请编辑或运行:
|
||||||
|
echo path = "E:\Scoop\apps\7zip\25.01\7z.exe" > "E:\Scoop\shims\7z.shim"
|
||||||
|
|
||||||
|
2. 创建 7zip current 符号链接
|
||||||
|
以管理员身份运行 CMD,执行:
|
||||||
|
mklink /J "E:\Scoop\apps\7zip\current" "E:\Scoop\apps\7zip\25.01"
|
||||||
|
|
||||||
|
如果无法创建符号链接,可以直接跳过此步,但需确保后续使用绝对路径。
|
||||||
|
|
||||||
|
3. 手动提取 Git 安装包
|
||||||
|
在 PowerShell 中执行:
|
||||||
|
& "E:\Scoop\apps\7zip\25.01\7z.exe" x "E:\Scoop\apps\git\2.53.0.2\dl.7z" -o"E:\Scoop\apps\git\2.53.0.2" -y
|
||||||
|
|
||||||
|
等待提取完成。
|
||||||
|
|
||||||
|
4. 检查提取结果
|
||||||
|
执行:
|
||||||
|
dir "E:\Scoop\apps\git\2.53.0.2"
|
||||||
|
|
||||||
|
应该看到 bin、cmd、etc 等目录。
|
||||||
|
|
||||||
|
5. 创建 Git shim 文件
|
||||||
|
创建 E:\Scoop\shims\git.shim:
|
||||||
|
echo path = "E:\Scoop\apps\git\2.53.0.2\bin\git.exe" > "E:\Scoop\shims\git.shim"
|
||||||
|
|
||||||
|
创建 shim 可执行文件:
|
||||||
|
copy "E:\Scoop\shims\7z.exe" "E:\Scoop\shims\git.exe"
|
||||||
|
|
||||||
|
6. 创建 sh (bash) shim
|
||||||
|
echo path = "E:\Scoop\apps\git\2.53.0.2\bin\sh.exe" > "E:\Scoop\shims\sh.shim"
|
||||||
|
|
||||||
|
7. 创建 git-bash shim
|
||||||
|
echo path = "E:\Scoop\apps\git\2.53.0.2\git-bash.exe" > "E:\Scoop\shims\git-bash.shim"
|
||||||
|
|
||||||
|
8. 更新 PATH 环境变量(临时)
|
||||||
|
在 PowerShell 中执行:
|
||||||
|
$env:Path = "E:\Scoop\shims;$env:Path"
|
||||||
|
|
||||||
|
9. 测试安装
|
||||||
|
执行:
|
||||||
|
git --version
|
||||||
|
sh --version
|
||||||
|
|
||||||
|
如果显示版本信息,则安装成功。
|
||||||
|
|
||||||
|
10. 永久添加 PATH(可选)
|
||||||
|
将 E:\Scoop\shims 添加到系统 PATH 环境变量:
|
||||||
|
[Environment]::SetEnvironmentVariable("Path", "E:\Scoop\shims;" + [Environment]::GetEnvironmentVariable("Path", "User"), "User")
|
||||||
|
|
||||||
|
重启终端使更改生效。
|
||||||
|
|
||||||
|
如果仍有问题,可以临时使用完整路径:
|
||||||
|
E:\Scoop\apps\git\2.53.0.2\bin\git.exe
|
||||||
Loading…
Reference in New Issue
Block a user