update
All checks were successful
Deploy to Production / deploy (push) Successful in 20s

This commit is contained in:
vuongps38770
2026-02-28 20:00:38 +07:00
parent f96833a7e4
commit 72283443ab
15 changed files with 972 additions and 318 deletions

View File

@@ -60,10 +60,10 @@ const { Op } = require('sequelize');
*/
exports.createVocab = async (req, res) => {
try {
const {
const {
text,
ipa,
base_word,
base_word,
vi,
category,
topic,
@@ -160,16 +160,18 @@ exports.createVocab = async (req, res) => {
*/
exports.getAllVocabs = async (req, res) => {
try {
const {
page = 1,
limit = 20,
category,
const {
page = 1,
limit = 20,
category,
topic,
base_word,
text,
search,
grade_start,
grade_end,
status,
sort,
is_active = true
} = req.query;
@@ -181,6 +183,11 @@ exports.getAllVocabs = async (req, res) => {
where.is_active = is_active === 'true' || is_active === true;
}
// Status filter (0 = chưa duyệt, 1 = đã duyệt, undefined = all)
if (status !== undefined && status !== '' && status !== 'all') {
where.status = parseInt(status);
}
if (category) {
where.category = category;
}
@@ -221,11 +228,19 @@ exports.getAllVocabs = async (req, res) => {
where.grade_number = { [Op.lte]: parseInt(grade_end) };
}
// Sort order
let order = [['created_at', 'DESC']]; // default
if (sort === 'updated_at') {
order = [['updated_at', 'DESC']];
} else if (sort === 'alphabet') {
order = [['text', 'ASC']];
}
const { count, rows } = await Vocab.findAndCountAll({
where,
limit: parseInt(limit),
offset: parseInt(offset),
order: [['created_at', 'DESC']]
order
});
res.json({
@@ -276,9 +291,9 @@ exports.getVocabById = async (req, res) => {
const { id } = req.params;
const vocab = await Vocab.findOne({
where: {
where: {
vocab_id: id,
is_active: true
is_active: true
}
});
@@ -339,7 +354,7 @@ exports.getVocabsWithoutIpa = async (req, res) => {
const offset = (page - 1) * limit;
const { count, rows } = await Vocab.findAndCountAll({
where: {
where: {
is_active: true,
[Op.or]: [
{ ipa: null },
@@ -407,7 +422,7 @@ exports.getVocabsWithoutImages = async (req, res) => {
const offset = (page - 1) * limit;
const { count, rows } = await Vocab.findAndCountAll({
where: {
where: {
is_active: true,
[Op.or]: [
{ image_small: null },
@@ -798,7 +813,7 @@ exports.getVocabStats = async (req, res) => {
*/
exports.searchVocabs = async (req, res) => {
try {
const {
const {
topic,
category,
base_word,
@@ -876,7 +891,7 @@ exports.searchVocabs = async (req, res) => {
// Handle shuffle_pos: find replacement words based on syntax
if (shuffle_pos && typeof shuffle_pos === 'object') {
const syntaxConditions = [];
if (shuffle_pos.is_subject === true) {
syntaxConditions.push({ 'syntax.is_subject': true });
}
@@ -911,7 +926,7 @@ exports.searchVocabs = async (req, res) => {
true
);
});
if (orConditions.length === 1) {
where[Op.and] = where[Op.and] || [];
where[Op.and].push(orConditions[0]);
@@ -975,7 +990,7 @@ exports.searchVocabs = async (req, res) => {
exports.getAllCategories = async (req, res) => {
try {
const categories = await Vocab.findAll({
where: {
where: {
is_active: true,
category: { [Op.ne]: null }
},
@@ -1026,7 +1041,7 @@ exports.getAllCategories = async (req, res) => {
exports.getAllTopics = async (req, res) => {
try {
const topics = await Vocab.findAll({
where: {
where: {
is_active: true,
topic: { [Op.ne]: null }
},