|
@@ -1,6 +1,6 @@
|
|
|
const express = require('express');
|
|
|
const router = express.Router();
|
|
|
-const {Article} = require('../../models')
|
|
|
+const {Article, Category} = require('../../models')
|
|
|
const {Op} = require('sequelize')
|
|
|
|
|
|
/*
|
|
@@ -23,17 +23,53 @@ router.get('/', async function(req, res, next) {
|
|
|
const condition = {
|
|
|
order:[['id','DESC']],
|
|
|
limit:pageSize,
|
|
|
- offset
|
|
|
+ offset,
|
|
|
+ include: [{
|
|
|
+ model: Category,
|
|
|
+ as: 'categoryInfo',
|
|
|
+ attributes: ['id', 'name', 'level', 'parentId'],
|
|
|
+ required: false // LEFT JOIN,即使没有分类也能返回文章
|
|
|
+ }]
|
|
|
}
|
|
|
|
|
|
+ // 构建查询条件
|
|
|
+ const whereConditions = {};
|
|
|
+
|
|
|
+ // 标题搜索
|
|
|
if(query.title){
|
|
|
- condition.where = {
|
|
|
- title:{
|
|
|
- [Op.like]:`%${query.title}%`
|
|
|
- }
|
|
|
+ whereConditions.title = {
|
|
|
+ [Op.like]:`%${query.title}%`
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 分类筛选 - 支持多选和包含子分类
|
|
|
+ if(query.categoryIds){
|
|
|
+ let categoryIds = [];
|
|
|
+
|
|
|
+ // 处理categoryIds参数(支持逗号分隔的多个ID)
|
|
|
+ if(typeof query.categoryIds === 'string'){
|
|
|
+ categoryIds = query.categoryIds.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id));
|
|
|
+ } else if(Array.isArray(query.categoryIds)){
|
|
|
+ categoryIds = query.categoryIds.map(id => parseInt(id)).filter(id => !isNaN(id));
|
|
|
+ } else {
|
|
|
+ categoryIds = [parseInt(query.categoryIds)].filter(id => !isNaN(id));
|
|
|
+ }
|
|
|
+
|
|
|
+ if(categoryIds.length > 0){
|
|
|
+ // 获取所有选中的分类及其子分类的ID
|
|
|
+ const allCategoryIds = await getAllCategoryIdsWithChildren(categoryIds);
|
|
|
+
|
|
|
+ whereConditions.category = {
|
|
|
+ [Op.in]: allCategoryIds
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果有查询条件,添加到condition中
|
|
|
+ if(Object.keys(whereConditions).length > 0){
|
|
|
+ condition.where = whereConditions;
|
|
|
+ }
|
|
|
+
|
|
|
const {count ,rows} = await Article.findAndCountAll(condition)
|
|
|
|
|
|
res.json({
|
|
@@ -67,7 +103,14 @@ router.get('/:id', async function(req, res, next) {
|
|
|
const {id} = req.params
|
|
|
|
|
|
//查询文章
|
|
|
- const article = await Article.findByPk(id)
|
|
|
+ const article = await Article.findByPk(id, {
|
|
|
+ include: [{
|
|
|
+ model: Category,
|
|
|
+ as: 'categoryInfo',
|
|
|
+ attributes: ['id', 'name', 'level', 'parentId'],
|
|
|
+ required: false
|
|
|
+ }]
|
|
|
+ })
|
|
|
|
|
|
if(article){
|
|
|
res.json({
|
|
@@ -241,6 +284,50 @@ router.put('/:id', async function(req, res, next) {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+/**
|
|
|
+ * 获取分类及其所有子分类的ID列表
|
|
|
+ * @param {Array} categoryIds - 分类ID数组
|
|
|
+ * @returns {Promise<Array>} 包含所有分类ID的数组
|
|
|
+ */
|
|
|
+async function getAllCategoryIdsWithChildren(categoryIds) {
|
|
|
+ try {
|
|
|
+ let allIds = [...categoryIds];
|
|
|
+
|
|
|
+ // 递归获取所有子分类
|
|
|
+ async function getChildrenIds(parentIds) {
|
|
|
+ if (parentIds.length === 0) return [];
|
|
|
+
|
|
|
+ const children = await Category.findAll({
|
|
|
+ where: {
|
|
|
+ parentId: {
|
|
|
+ [Op.in]: parentIds
|
|
|
+ }
|
|
|
+ },
|
|
|
+ attributes: ['id']
|
|
|
+ });
|
|
|
+
|
|
|
+ const childrenIds = children.map(child => child.id);
|
|
|
+ if (childrenIds.length > 0) {
|
|
|
+ allIds = allIds.concat(childrenIds);
|
|
|
+ // 递归获取子分类的子分类
|
|
|
+ const grandChildrenIds = await getChildrenIds(childrenIds);
|
|
|
+ allIds = allIds.concat(grandChildrenIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ return childrenIds;
|
|
|
+ }
|
|
|
+
|
|
|
+ await getChildrenIds(categoryIds);
|
|
|
+
|
|
|
+ // 去重并返回
|
|
|
+ return [...new Set(allIds)];
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取分类ID列表错误:', error);
|
|
|
+ // 如果出错,返回原始ID列表
|
|
|
+ return categoryIds;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
function filterBody(req){
|
|
|
try {
|
|
|
// 数据清理和验证
|