33 * 负责初始化示例数据并自动加载到UI
44 */
55
6- import { useEffect , useState , useRef } from 'react' ;
6+ import { useEffect , useState , useRef , useCallback } from 'react' ;
77import { initializeSampleData } from '@/services/initializeSampleData' ;
88import { useProjectStore } from '@/store/projectStore' ;
99import { useVersionStore } from '@/store/versionStore' ;
1010import { useSettingsStore } from '@/store/settingsStore' ;
11+ import { useTranslation } from '@/i18n/I18nContext' ;
1112import { storage , STORAGE_KEYS } from '@/utils/storage' ;
13+ import { db } from '@/db/schema' ;
1214
1315interface AppInitializerProps {
1416 children : React . ReactNode ;
1517}
1618
19+ /**
20+ * 从 URL hash 中解析项目 ID
21+ * 格式: #/project/{projectId}
22+ */
23+ const getProjectIdFromUrl = ( ) : string | null => {
24+ const hash = window . location . hash ;
25+ if ( ! hash ) return null ;
26+
27+ const match = hash . match ( / ^ # \/ p r o j e c t \/ ( .+ ) $ / ) ;
28+ return match ? match [ 1 ] : null ;
29+ } ;
30+
1731export const AppInitializer : React . FC < AppInitializerProps > = ( { children } ) => {
1832 const [ isInitialized , setIsInitialized ] = useState ( false ) ;
19- const { loadProjects, setCurrentProject, loadFolders } = useProjectStore ( ) ;
33+ const { loadProjects, setCurrentProject, loadFolders, expandFolderPathToProject } = useProjectStore ( ) ;
2034 const { loadVersions } = useVersionStore ( ) ;
2135 const { theme } = useSettingsStore ( ) ;
36+ const t = useTranslation ( ) ;
2237
2338 // 使用 ref 确保初始化只执行一次(防止 React 18 严格模式下的双重调用)
2439 const hasInitialized = useRef ( false ) ;
@@ -37,6 +52,13 @@ export const AppInitializer: React.FC<AppInitializerProps> = ({ children }) => {
3752 applyTheme ( theme === 'dark' ) ;
3853 } , [ theme ] ) ;
3954
55+ // 处理从 URL 打开项目的函数
56+ const handleOpenProjectFromUrl = useCallback ( async ( projectId : string ) => {
57+ setCurrentProject ( projectId ) ;
58+ await expandFolderPathToProject ( projectId ) ;
59+ await loadVersions ( projectId ) ;
60+ } , [ setCurrentProject , expandFolderPathToProject , loadVersions ] ) ;
61+
4062 useEffect ( ( ) => {
4163 // 如果已经初始化过,直接返回
4264 if ( hasInitialized . current ) {
@@ -48,10 +70,26 @@ export const AppInitializer: React.FC<AppInitializerProps> = ({ children }) => {
4870 // 初始化示例数据
4971 const sampleProjectId = await initializeSampleData ( ) ;
5072
51- // 如果创建了示例项目,自动加载和选择它
52- if ( sampleProjectId ) {
53- await loadFolders ( ) ;
54- await loadProjects ( ) ;
73+ // 加载文件夹和项目
74+ await loadFolders ( ) ;
75+ await loadProjects ( ) ;
76+
77+ // 检查 URL 中是否有项目 ID 参数
78+ const urlProjectId = getProjectIdFromUrl ( ) ;
79+
80+ if ( urlProjectId ) {
81+ // 验证项目是否存在
82+ const project = await db . projects . get ( urlProjectId ) ;
83+ if ( project ) {
84+ // 项目存在,打开它
85+ await handleOpenProjectFromUrl ( urlProjectId ) ;
86+ } else {
87+ // 项目不存在,提示用户并重置 URL
88+ alert ( t ( 'errors.projectNotFound' ) ) ;
89+ window . open ( '/' , '_self' ) ;
90+ }
91+ } else if ( sampleProjectId ) {
92+ // 如果创建了示例项目,自动加载和选择它
5593 setCurrentProject ( sampleProjectId ) ;
5694 await loadVersions ( sampleProjectId ) ;
5795 }
@@ -65,7 +103,7 @@ export const AppInitializer: React.FC<AppInitializerProps> = ({ children }) => {
65103 } ;
66104
67105 initialize ( ) ;
68- } , [ loadProjects , loadFolders , setCurrentProject , loadVersions ] ) ;
106+ } , [ loadProjects , loadFolders , setCurrentProject , loadVersions , handleOpenProjectFromUrl , t ] ) ;
69107
70108 // 在初始化完成前,可以显示一个简单的加载提示
71109 if ( ! isInitialized ) {
0 commit comments