94 lines
3.8 KiB
JavaScript
94 lines
3.8 KiB
JavaScript
const mongoose = require('mongoose');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const connectDB = require('../config/db');
|
|
const Scene = require('../models/Scene');
|
|
const Hotspot = require('../models/Hotspot');
|
|
|
|
/**
|
|
* Script migration chuẩn hóa trường tourId cho tất cả các Scene dựa trên liên kết Hotspot thực tế.
|
|
* Đảm bảo tính nhất quán cho các tính năng Privacy Cascading và Cascade Delete.
|
|
*/
|
|
const migrateTourIds = async () => {
|
|
try {
|
|
console.log('--- Bắt đầu quy trình chuẩn hóa tourId ---');
|
|
await connectDB();
|
|
|
|
// Bước 1: Xóa bỏ các giá trị tourId rác (null, rỗng) để xử lý sạch
|
|
await Scene.updateMany(
|
|
{ tourId: { $in: [null, ""] } },
|
|
{ $unset: { tourId: 1 } }
|
|
);
|
|
|
|
// Bước 2: Tìm các cảnh gốc (Roots)
|
|
// Cảnh gốc là cảnh không có bất kỳ hotspot đi tới nào (không tính link quay lại - is_auto_return)
|
|
const targetSceneIds = await Hotspot.find({ is_auto_return: { $ne: true } }).distinct('target_scene_id');
|
|
const rootScenes = await Scene.find({ _id: { $nin: targetSceneIds } });
|
|
|
|
console.log(`- Tìm thấy ${rootScenes.length} cảnh gốc tiềm năng.`);
|
|
|
|
const processedScenes = new Set();
|
|
let updatedCount = 0;
|
|
|
|
for (const root of rootScenes) {
|
|
const rootIdStr = root._id.toString();
|
|
if (processedScenes.has(rootIdStr)) continue;
|
|
|
|
console.log(`- Đang xử lý Tour: ${root.name || root.title || root._id}`);
|
|
|
|
// Cập nhật rootId cho chính nó
|
|
await Scene.updateOne({ _id: root._id }, { $set: { tourId: root._id } });
|
|
processedScenes.add(rootIdStr);
|
|
updatedCount++;
|
|
|
|
// Duyệt BFS để gán tourId cho toàn bộ cây tour
|
|
let queue = [root._id];
|
|
while (queue.length > 0) {
|
|
const parentId = queue.shift();
|
|
|
|
const hotspots = await Hotspot.find({
|
|
parent_scene_id: parentId,
|
|
is_auto_return: { $ne: true }
|
|
});
|
|
|
|
for (const hs of hotspots) {
|
|
if (hs.target_scene_id) {
|
|
const childIdStr = hs.target_scene_id.toString();
|
|
if (!processedScenes.has(childIdStr)) {
|
|
await Scene.updateOne(
|
|
{ _id: hs.target_scene_id },
|
|
{ $set: { tourId: root._id } }
|
|
);
|
|
processedScenes.add(childIdStr);
|
|
updatedCount++;
|
|
queue.push(hs.target_scene_id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Bước 3: Xử lý các cảnh mồ côi, lỗi tourId null/rỗng hoặc vòng lặp kín
|
|
const orphanScenes = await Scene.find({
|
|
$or: [{ tourId: { $exists: false } }, { tourId: null }, { tourId: "" }]
|
|
});
|
|
let orphanCount = 0;
|
|
for (const scene of orphanScenes) {
|
|
await Scene.updateOne({ _id: scene._id }, { $set: { tourId: scene._id } });
|
|
orphanCount++;
|
|
}
|
|
|
|
console.log(`- Đã cập nhật ${updatedCount} cảnh theo luồng tour.`);
|
|
console.log(`- Đã xử lý ${orphanCount} cảnh mồ côi/vòng lặp tự trỏ về chính mình.`);
|
|
console.log('--- Hoàn tất migration tourId! ---');
|
|
|
|
mongoose.connection.close();
|
|
process.exit(0);
|
|
} catch (error) {
|
|
console.error('Lỗi Migration:', error.message);
|
|
if (mongoose.connection) mongoose.connection.close();
|
|
process.exit(1);
|
|
}
|
|
};
|
|
|
|
migrateTourIds(); |