88 lines
3.0 KiB
TypeScript
88 lines
3.0 KiB
TypeScript
/**
|
|
* 把旧库数据编排成新库可直接写入的数据集。
|
|
*
|
|
* 逻辑集中在这里,migrate.ts(写库)与 transform.test.ts(校验)共用同一份实现,
|
|
* 避免两边各写一遍导致漂移。
|
|
*/
|
|
|
|
import { asString, type LegacyRows } from './load';
|
|
import {
|
|
HOME_COURSE_TITLE_MAP,
|
|
transformArticle,
|
|
transformBanner,
|
|
transformCourse,
|
|
transformCourseTip,
|
|
transformEntitlement,
|
|
transformFreeLesson,
|
|
transformHomeCourse,
|
|
transformHomeFreeCourse,
|
|
transformLesson,
|
|
transformSetting,
|
|
transformUser,
|
|
} from './transform';
|
|
|
|
export type Dataset = ReturnType<typeof buildDataset>;
|
|
|
|
export function buildDataset(db: LegacyRows, staticBase: string) {
|
|
// 先建课程,得到 code → 自增 id 的映射(新库 id 从 1 开始,与插入顺序一致)
|
|
const courses = db.课程口令码读取信息.map(transformCourse);
|
|
const courseIdByCode = new Map(courses.map((c, i) => [c.code, i + 1]));
|
|
const courseIdByTitle = new Map(courses.map((c, i) => [c.title, i + 1]));
|
|
|
|
const users = db.用户信息.map(transformUser);
|
|
const userIdByOpenid = new Map(users.map((u, i) => [u.openid, i + 1]));
|
|
|
|
const skippedLessonOrphans: string[] = [];
|
|
const lessons = db.视频课程数据.flatMap((row) => {
|
|
const courseId = courseIdByCode.get(asString(row.课程id));
|
|
if (!courseId) {
|
|
skippedLessonOrphans.push(asString(row.课程id));
|
|
return [];
|
|
}
|
|
return [transformLesson(row, courseId)];
|
|
});
|
|
|
|
// 权益:按 (user, course) 去重,重复的只保留第一条
|
|
const seen = new Set<string>();
|
|
const duplicateEntitlements: string[] = [];
|
|
const entitlements = db.用户已购课程.flatMap((row) => {
|
|
const userId = userIdByOpenid.get(asString(row.OpenID));
|
|
const courseId = courseIdByCode.get(asString(row.课程id));
|
|
if (!userId || !courseId) return [];
|
|
const key = `${userId}::${courseId}`;
|
|
if (seen.has(key)) {
|
|
duplicateEntitlements.push(key);
|
|
return [];
|
|
}
|
|
seen.add(key);
|
|
return [transformEntitlement(row, userId, courseId)];
|
|
});
|
|
|
|
const unmappedHomeCourses: string[] = [];
|
|
const homeCourses = db.首页课程列表.map((row) => {
|
|
const courseName = asString(row.课程名称);
|
|
const title = HOME_COURSE_TITLE_MAP[courseName];
|
|
const courseId = title ? courseIdByTitle.get(title) ?? null : null;
|
|
if (courseId === null) unmappedHomeCourses.push(courseName);
|
|
return transformHomeCourse(row, courseId, staticBase);
|
|
});
|
|
|
|
return {
|
|
courses,
|
|
users,
|
|
lessons,
|
|
entitlements,
|
|
homeCourses,
|
|
freeLessons: db.免费视频课程数据.map(transformFreeLesson),
|
|
homeFreeCourses: db.首页免费课程列表.map(transformHomeFreeCourse),
|
|
banners: db.首页横幅图片.map(transformBanner),
|
|
articles: db.网页列表.map((row) => transformArticle(row, staticBase)),
|
|
courseTips: db.课程页面Tips.map(transformCourseTip),
|
|
settings: db.cloudconfig
|
|
.map(transformSetting)
|
|
.filter((v): v is NonNullable<typeof v> => v !== null),
|
|
diagnostics: { skippedLessonOrphans, duplicateEntitlements, unmappedHomeCourses },
|
|
};
|
|
}
|
|
|