forked from UKSOURCE/cms.hailearning.edu.vn
API Country
This commit is contained in:
@@ -44,7 +44,15 @@ const addBaseUrlToImages = (data, baseUrl) => {
|
||||
return data;
|
||||
};
|
||||
const Visa = require("../models/visa");
|
||||
|
||||
const slugify = require("slugify");
|
||||
const createSlug = (text) => {
|
||||
return slugify(text, {
|
||||
lower: true, // Chuyển về chữ thường
|
||||
strict: true, // Loại bỏ ký tự đặc biệt
|
||||
locale: "vi", // Xử lý tiếng Việt chuẩn
|
||||
trim: true,
|
||||
});
|
||||
};
|
||||
// -------------------- Helper Functions --------------------
|
||||
|
||||
// Get visa data from MongoDB
|
||||
@@ -108,24 +116,65 @@ exports.index = async (req, res) => {
|
||||
|
||||
// Get single country for edit
|
||||
exports.getCountry = async (req, res) => {
|
||||
console.log("--------------------------------------------------");
|
||||
console.log("🚀 [GET] Request nhận được tại /visa/edit/:id");
|
||||
|
||||
try {
|
||||
const { slug } = req.params;
|
||||
const { id } = req.params;
|
||||
console.log("📍 ID từ Params (URL):", id, "| Kiểu dữ liệu:", typeof id);
|
||||
|
||||
const visaData = await getVisaData();
|
||||
|
||||
if (!visaData.hero || !visaData.hero.summaryList) {
|
||||
return res.status(404).json({ error: "Visa data not found" });
|
||||
// Kiểm tra cấu trúc dữ liệu tổng
|
||||
if (!visaData) {
|
||||
console.error("❌ Lỗi: Hàm getVisaData() trả về null/undefined");
|
||||
return res.status(404).json({ error: "Dữ liệu gốc không tồn tại" });
|
||||
}
|
||||
|
||||
const country = visaData.hero.summaryList.find((c) => c.slug === slug);
|
||||
if (!visaData.hero || !visaData.hero.summaryList) {
|
||||
console.error("❌ Lỗi: Cấu trúc visaData.hero.summaryList không hợp lệ");
|
||||
return res
|
||||
.status(404)
|
||||
.json({ error: "Không tìm thấy danh sách quốc gia" });
|
||||
}
|
||||
|
||||
console.log(
|
||||
"📊 Tổng số quốc gia hiện có trong mảng:",
|
||||
visaData.hero.summaryList.length,
|
||||
);
|
||||
|
||||
// 2. Tìm quốc gia theo ID
|
||||
const targetId = parseInt(id);
|
||||
console.log("🔍 Đang tìm kiếm Quốc gia có ID (sau khi parse):", targetId);
|
||||
|
||||
const country = visaData.hero.summaryList.find((c) => {
|
||||
// Log từng phần tử để kiểm tra kiểu dữ liệu của c.id trong DB
|
||||
// console.log(`Checking country: ${c.name} | ID in DB: ${c.id} (${typeof c.id})`);
|
||||
return c.id === targetId;
|
||||
});
|
||||
|
||||
if (!country) {
|
||||
return res.status(404).json({ error: `Country "${slug}" not found` });
|
||||
console.warn(`⚠️ Không tìm thấy quốc gia nào khớp với ID: ${targetId}`);
|
||||
// In ra danh sách ID hiện có để so sánh
|
||||
const existingIds = visaData.hero.summaryList.map((c) => c.id);
|
||||
console.log("🆔 Các ID hiện có trong Database:", existingIds);
|
||||
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: `Không tìm thấy quốc gia có ID: ${id}`,
|
||||
});
|
||||
}
|
||||
|
||||
res.json(country);
|
||||
console.log("✅ Tìm thấy dữ liệu quốc gia:", country.name);
|
||||
|
||||
// 3. Trả về dữ liệu
|
||||
res.json({
|
||||
success: true,
|
||||
country: country,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Get country error:", err);
|
||||
res.status(500).json({ error: "Error loading country" });
|
||||
console.error("🔴 Lỗi nghiêm trọng tại getCountry Controller:", err);
|
||||
res.status(500).json({ error: "Lỗi hệ thống khi tải thông tin quốc gia" });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -195,19 +244,12 @@ exports.addCountry = async (req, res) => {
|
||||
}
|
||||
|
||||
// Validate required fields
|
||||
if (!req.body.name || !req.body.slug) {
|
||||
return res.status(400).json({ error: "Name and slug are required" });
|
||||
}
|
||||
|
||||
// Check if slug already exists
|
||||
const slugExists = visaData.hero.summaryList.some(
|
||||
(c) => c.slug === req.body.slug,
|
||||
);
|
||||
if (slugExists) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: `Slug "${req.body.slug}" already exists` });
|
||||
if (!req.body.name) {
|
||||
return res.status(400).json({ error: "Name is required" });
|
||||
}
|
||||
const finalSlug = req.body.slug
|
||||
? createSlug(req.body.slug)
|
||||
: createSlug(req.body.name);
|
||||
|
||||
// Parse services array
|
||||
let services = [];
|
||||
@@ -240,7 +282,7 @@ exports.addCountry = async (req, res) => {
|
||||
const newCountry = {
|
||||
id: req.body.id || getNextCountryId(visaData.hero.summaryList),
|
||||
name: req.body.name,
|
||||
slug: req.body.slug,
|
||||
slug: finalSlug,
|
||||
icon: req.body.icon || "",
|
||||
services: services,
|
||||
...(detailedView && { detailedView }),
|
||||
@@ -278,77 +320,88 @@ exports.addCountry = async (req, res) => {
|
||||
// Update single country
|
||||
exports.updateCountry = async (req, res) => {
|
||||
try {
|
||||
const { slug } = req.params;
|
||||
// 1. Lấy ID từ params (URL)
|
||||
const { id } = req.params;
|
||||
let visaData = await getVisaData();
|
||||
|
||||
if (!visaData.hero || !visaData.hero.summaryList) {
|
||||
return res.status(400).json({ error: "Invalid visa data structure" });
|
||||
}
|
||||
// if (!visaData || !visaData.hero || !visaData.hero.summaryList) {
|
||||
// return res
|
||||
// .status(400)
|
||||
// .json({ error: "Cấu trúc dữ liệu Visa không hợp lệ" });
|
||||
// }
|
||||
|
||||
// 2. Tìm index theo ID (Chuyển về Number để so sánh chính xác)
|
||||
const countryIndex = visaData.hero.summaryList.findIndex(
|
||||
(c) => c.slug === slug,
|
||||
(c) => c.id === parseInt(id),
|
||||
);
|
||||
|
||||
if (countryIndex === -1) {
|
||||
return res.status(404).json({ error: `Country "${slug}" not found` });
|
||||
return res
|
||||
.status(404)
|
||||
.json({ error: `Không tìm thấy quốc gia có ID: ${id}` });
|
||||
}
|
||||
|
||||
const currentCountry = visaData.hero.summaryList[countryIndex];
|
||||
|
||||
// Parse services array
|
||||
let services = currentCountry.services || [];
|
||||
if (req.body.services) {
|
||||
if (typeof req.body.services === "string") {
|
||||
try {
|
||||
services = JSON.parse(req.body.services);
|
||||
} catch (e) {
|
||||
services = [req.body.services];
|
||||
}
|
||||
} else if (Array.isArray(req.body.services)) {
|
||||
services = req.body.services;
|
||||
}
|
||||
let finalSlug = currentCountry.slug;
|
||||
if (req.body.name) {
|
||||
// Nếu name thay đổi, ta có thể cập nhật lại slug (tùy nhu cầu SEO)
|
||||
// Ở đây ưu tiên: Nếu có slug mới truyền lên thì dùng, không thì tạo từ name mới
|
||||
finalSlug = req.body.slug
|
||||
? createSlug(req.body.slug)
|
||||
: createSlug(req.body.name);
|
||||
}
|
||||
|
||||
// Parse detailedView if provided (optional)
|
||||
let detailedView = currentCountry.detailedView;
|
||||
if (req.body.detailedView) {
|
||||
// 3. Xử lý dữ liệu từ req.body
|
||||
// Vì Client đã gửi JSON stringify, ta lấy trực tiếp hoặc parse nếu cần
|
||||
let services = req.body.services;
|
||||
if (typeof services === "string") {
|
||||
try {
|
||||
detailedView =
|
||||
typeof req.body.detailedView === "string"
|
||||
? JSON.parse(req.body.detailedView)
|
||||
: req.body.detailedView;
|
||||
services = JSON.parse(services);
|
||||
} catch (e) {
|
||||
console.warn("Could not parse detailedView");
|
||||
services = [services];
|
||||
}
|
||||
}
|
||||
|
||||
// Update country data
|
||||
let detailedView = req.body.detailedView;
|
||||
if (typeof detailedView === "string") {
|
||||
try {
|
||||
detailedView = JSON.parse(detailedView);
|
||||
} catch (e) {
|
||||
detailedView = currentCountry.detailedView;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Cập nhật Object quốc gia
|
||||
const updatedCountry = {
|
||||
...currentCountry,
|
||||
...currentCountry, // Giữ các trường cũ
|
||||
id: parseInt(id), // Đảm bảo ID không đổi
|
||||
name: req.body.name || currentCountry.name,
|
||||
slug: req.body.slug || currentCountry.slug, // Allow slug update
|
||||
slug: finalSlug,
|
||||
icon: req.body.icon || currentCountry.icon,
|
||||
services: services,
|
||||
...(detailedView && { detailedView }),
|
||||
services: Array.isArray(services) ? services : currentCountry.services,
|
||||
detailedView: detailedView || currentCountry.detailedView,
|
||||
};
|
||||
|
||||
// 5. Cập nhật vào mảng chính
|
||||
visaData.hero.summaryList[countryIndex] = updatedCountry;
|
||||
|
||||
// Update database
|
||||
const updatedData = {
|
||||
...(visaData.toObject ? visaData.toObject() : visaData),
|
||||
};
|
||||
|
||||
if (visaData._id) {
|
||||
await Visa.findByIdAndUpdate(visaData._id, updatedData, { new: true });
|
||||
} else {
|
||||
await Visa.create(updatedData);
|
||||
// 6. Lưu vào Database
|
||||
if (visaData.markModified) {
|
||||
// Bắt buộc với Mongoose khi thay đổi nội dung bên trong Array/Object
|
||||
visaData.markModified("hero.summaryList");
|
||||
}
|
||||
|
||||
console.log(`✅ Country "${updatedCountry.name}" updated successfully`);
|
||||
if (visaData._id) {
|
||||
await visaData.save(); // Sử dụng save() trực tiếp nếu visaData là Mongoose Document
|
||||
} else {
|
||||
await Visa.create(visaData);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`✅ Country "${updatedCountry.name}" updated successfully by ID: ${id}`,
|
||||
);
|
||||
res.json({
|
||||
success: true,
|
||||
message: `Country "${updatedCountry.name}" updated successfully`,
|
||||
message: `Quốc gia "${updatedCountry.name}" đã được cập nhật thành công`,
|
||||
country: updatedCountry,
|
||||
});
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user