@@ -116,11 +116,34 @@ export const calculateNextReview = (problem, feedback) => {
116116 }
117117} ;
118118
119+ // 将状态转换为数字
120+ const stateToNumber = ( state ) => {
121+ switch ( state ) {
122+ case 'New' : return 0 ;
123+ case 'Learning' : return 1 ;
124+ case 'Review' : return 2 ;
125+ case 'Relearning' : return 3 ;
126+ default : return 0 ;
127+ }
128+ } ;
129+
119130// 5. 更新问题状态
120131export const updateProblemWithFSRS = ( problem , feedback ) => {
121132 const now = Date . now ( ) ;
122133 const fsrsResult = calculateNextReview ( problem , feedback ) ;
123-
134+
135+ // 创建新的复习日志条目,只包含必要字段
136+ const newRevlog = {
137+ card_id : problem . index , // 使用问题索引作为卡片ID
138+ review_time : now , // 复习时间(毫秒时间戳)
139+ review_rating : qualityToRating ( feedback . quality ) , // 复习评分 (1-4)
140+ review_state : stateToNumber ( problem . fsrsState ?. state || 'New' ) // 复习状态 (0-3)
141+ } ;
142+
143+ // 将复习日志存储到单独的 localStorage 键中
144+ saveRevlog ( problem . index , newRevlog ) ;
145+
146+ // 更新问题状态(不修改原有结构)
124147 problem . fsrsState = {
125148 ...problem . fsrsState ,
126149 difficulty : fsrsResult . difficulty ,
@@ -136,3 +159,93 @@ export const updateProblemWithFSRS = (problem, feedback) => {
136159 problem . modificationTime = now ;
137160 return problem ;
138161} ;
162+
163+ // 保存单个复习日志
164+ export const saveRevlog = async ( cardId , revlog ) => {
165+ try {
166+ // 从 localStorage 获取现有的复习日志
167+ const existingRevlogsStr = await new Promise ( ( resolve ) => {
168+ chrome . storage . local . get ( [ 'fsrs_revlogs' ] , ( result ) => {
169+ resolve ( result . fsrs_revlogs || '{}' ) ;
170+ } ) ;
171+ } ) ;
172+
173+ let existingRevlogs ;
174+ try {
175+ existingRevlogs = JSON . parse ( existingRevlogsStr ) ;
176+ } catch ( e ) {
177+ console . error ( 'Error parsing revlogs:' , e ) ;
178+ existingRevlogs = { } ;
179+ }
180+
181+ // 确保该卡片的日志数组存在
182+ if ( ! existingRevlogs [ cardId ] ) {
183+ existingRevlogs [ cardId ] = [ ] ;
184+ }
185+
186+ // 添加新的复习日志
187+ existingRevlogs [ cardId ] . push ( revlog ) ;
188+
189+ // 保存回 localStorage
190+ await new Promise ( ( resolve ) => {
191+ chrome . storage . local . set ( { 'fsrs_revlogs' : JSON . stringify ( existingRevlogs ) } ) ;
192+ resolve ( ) ;
193+ } ) ;
194+
195+ return true ;
196+ } catch ( error ) {
197+ console . error ( 'Error saving revlog:' , error ) ;
198+ return false ;
199+ }
200+ } ;
201+
202+ // 获取所有复习日志
203+ export const getAllRevlogs = async ( ) => {
204+ try {
205+ const revlogsStr = await new Promise ( ( resolve ) => {
206+ chrome . storage . local . get ( [ 'fsrs_revlogs' ] , ( result ) => {
207+ resolve ( result . fsrs_revlogs || '{}' ) ;
208+ } ) ;
209+ } ) ;
210+
211+ let allRevlogs ;
212+ try {
213+ allRevlogs = JSON . parse ( revlogsStr ) ;
214+ } catch ( e ) {
215+ console . error ( 'Error parsing revlogs:' , e ) ;
216+ return { } ;
217+ }
218+
219+ return allRevlogs ;
220+ } catch ( error ) {
221+ console . error ( 'Error getting revlogs:' , error ) ;
222+ return { } ;
223+ }
224+ } ;
225+
226+ // 导出复习日志为CSV格式
227+ export const exportRevlogsToCSV = async ( ) => {
228+ try {
229+ // 获取所有复习日志
230+ const allRevlogs = await getAllRevlogs ( ) ;
231+
232+ // CSV 头部 - 只包含必要字段
233+ const csvHeader = 'card_id,review_time,review_rating,review_state\n' ;
234+
235+ // 收集所有卡片的复习日志
236+ let csvContent = csvHeader ;
237+
238+ Object . keys ( allRevlogs ) . forEach ( cardId => {
239+ const cardRevlogs = allRevlogs [ cardId ] || [ ] ;
240+ cardRevlogs . forEach ( log => {
241+ // 只导出必要字段
242+ csvContent += `${ log . card_id } ,${ log . review_time } ,${ log . review_rating } ,${ log . review_state } \n` ;
243+ } ) ;
244+ } ) ;
245+
246+ return csvContent ;
247+ } catch ( error ) {
248+ console . error ( 'Error exporting revlogs to CSV:' , error ) ;
249+ return '' ;
250+ }
251+ } ;
0 commit comments