ソースを参照

fix: recover missing historical lesson subjects from original bookings

彭峰 4 時間 前
親
コミット
77b8d4722a

+ 5 - 5
scripts/cloud/lesson-records.js

@@ -38,7 +38,7 @@ async function lessonHistoryTypeRows(rows) {
  const saved=await Psql.query(`WITH wanted AS (SELECT DISTINCT * FROM jsonb_to_recordset($1::jsonb) AS w(company text,"appointmentId" numeric,"studentId" text))
  SELECT w.company,w."appointmentId"::text AS "appointmentId",w."studentId",
  r."courseCategoryKey" AS "reportKey",r."courseCategoryName" AS "reportName",r."durationMinutes" AS "reportMinutes",
- a."courseCategoryKey" AS "appointmentKey",a."courseCategoryName" AS "appointmentName",a."durationMinutes" AS "appointmentMinutes"
+ a.kcid AS "appointmentCourseId",a."courseCategoryKey" AS "appointmentKey",a."courseCategoryName" AS "appointmentName",a."durationMinutes" AS "appointmentMinutes"
  FROM wanted w
  LEFT JOIN LATERAL (SELECT a.* FROM "CommonModel" c JOIN "CourseAppointment" a ON a.company=c.company AND a.id=c."itemId" AND a.szyh::text=w."studentId"
  WHERE c.company=w.company AND c."modelId"=54 AND c."generalId"=w."appointmentId" ORDER BY c."objectId" LIMIT 1) a ON true
@@ -48,16 +48,16 @@ async function lessonHistoryTypeRows(rows) {
  return rows.map(row=>{
   const source=byAppointment.get(key({company:row.company,appointmentId:text(row.yyds),studentId:text(row.xymz)}))||{};
   const own=text(row.courseCategoryKey)||text(row.courseCategoryName),report=text(source.reportKey)||text(source.reportName);
-  return {...row,courseCategoryKey:own?row.courseCategoryKey:report?source.reportKey:source.appointmentKey,
+  return {...row,resolvedCourseId:text(row.kcid)||text(source.appointmentCourseId),courseCategoryKey:own?row.courseCategoryKey:report?source.reportKey:source.appointmentKey,
    courseCategoryName:own?row.courseCategoryName:report?source.reportName:source.appointmentName,
    durationMinutes:[source.reportMinutes,source.appointmentMinutes,row.durationMinutes].map(value=>number(value)).find(value=>value>0)};
  });
 }
 function lessonHistoryClassType(row) {
- const categoryKey=text(row.courseCategoryKey),categoryName=text(row.courseCategoryName),type=text(row.kclx);
+ const categoryKey=text(row.courseCategoryKey),categoryName=text(row.courseCategoryName),type=text(row.kclx),courseId=number(row.kcid)||number(row.resolvedCourseId);
  const minutes=number(row.durationMinutes)||({'1':30,'2':60,'3':60})[type];
- const isWord=categoryKey==='word'||categoryName==='单词课'||(!categoryKey&&!categoryName&&number(row.kcid)>0&&number(row.kcid)!==398&&['1','2'].includes(type));
- const name=categoryName||TEACHING_CATEGORY_LABELS.get(categoryKey)||(type==='3'?'体验课':isWord?'单词课':number(row.kcid)===398?'语法写作课':'');
+ const isWord=categoryKey==='word'||categoryName==='单词课'||(!categoryKey&&!categoryName&&courseId>0&&courseId!==398&&['1','2'].includes(type));
+ const name=categoryName||TEACHING_CATEGORY_LABELS.get(categoryKey)||(type==='3'?'体验课':isWord?'单词课':courseId===398?'语法写作课':'');
  return name?name+(minutes?' '+minutes+' 分钟':''):classType(row.kclx);
 }
 function lessonHistoryRow(row){return {targetId:text(row.targetId||row.objectId),lessonId:row.objectId,generalId:number(row.generalId||row.id),appointmentId:text(row.yyds),studentId:number(row.xymz),studentName:row.studentNameResolved,coachId:number(row.jsmz),coachName:row.coachNameResolved,storeId:number(row.storeIdResolved),storeName:row.storeName,courseId:number(row.kcid),courseName:row.courseNameResolved,classTypeLabel:lessonHistoryClassType(row),lessonAt:dateIso(row.actualAt),score:number(row.pf),comment:text(row.pldp),coachComment:text(row.pldp),studentComment:text(row.pjnr),feedbackSummary:text(row.feedbackSummary||row.pldp),duplicateCount:number(row.duplicates),pendingReviews:number(row.pendingReviews),reviewCoaches:row.reviewCoaches||[],reviewCoachLabel:(row.reviewCoaches||[]).length>1?'多位陪练':row.reviewCoaches?.[0]?.name||'无待复习任务'};}

+ 1 - 1
scripts/tests/fixtures/lesson-records-schema.sql

@@ -10,4 +10,4 @@ CREATE TABLE "_User" ("objectId" text PRIMARY KEY, "createdAt" timestamp with ti
 CREATE TABLE "Node" (company text,"nodeId" numeric,"nodeName" text);
 CREATE TABLE "LessonReview" (company text,"appointmentGeneralId" text,score numeric,comment text,"submittedAt" timestamptz);
 
-CREATE TABLE "CourseAppointment" ("objectId" text PRIMARY KEY,company text,id numeric,szyh text,"courseCategoryKey" text,"courseCategoryName" text,"durationMinutes" double precision);
+CREATE TABLE "CourseAppointment" ("objectId" text PRIMARY KEY,company text,id numeric,szyh text,kcid text,"courseCategoryKey" text,"courseCategoryName" text,"durationMinutes" double precision);

+ 5 - 0
scripts/tests/lesson-records.test.mjs

@@ -130,4 +130,9 @@ test('已确认预约补齐历史写作课型,按原学员和帐套关联,
  assert.equal(ctx.lessonHistoryClassType((await ctx.lessonHistoryTypeRows([base]))[0]),'中学语法写作课 30 分钟');
  assert.equal(ctx.lessonHistoryClassType({kcid:'30',kclx:'3'}),'体验课 60 分钟');
  assert.equal(ctx.lessonHistoryClassType({kcid:'30',kclx:'1'}),'单词课 30 分钟');
+ await query(`UPDATE "CourseAppointment" SET kcid='203',"courseCategoryKey"=NULL,"courseCategoryName"=NULL WHERE "objectId"='writing'`);
+ await query(`DELETE FROM "LessonCompletionReport" WHERE "objectId"='writingSnapshot'`);
+ assert.equal(ctx.lessonHistoryClassType((await ctx.lessonHistoryTypeRows([{...base,kcid:''}]))[0]),'单词课 60 分钟');
+ assert.equal(ctx.lessonHistoryClassType((await ctx.lessonHistoryTypeRows([{...base,kcid:'',company:'other'}]))[0]),'60 分钟');
+
 });