articles.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. const express = require('express');
  2. const router = express.Router();
  3. const {Article} = require('../../models')
  4. const {Op} = require('sequelize')
  5. /*
  6. 查询文章列表
  7. GET /admin/articles
  8. */
  9. router.get('/', async function(req, res, next) {
  10. try {
  11. const query = req.query
  12. //当前是第几页,如果不传,那就是第一页
  13. const currentPage = Math.abs(Number(query.currentPage)) || 1
  14. //每页显示多少条数据,如果不传,那就显示10条
  15. const pageSize = Math.abs(Number(query.pageSize)) || 10
  16. //计算 offset
  17. const offset = (currentPage - 1) * pageSize
  18. const condition = {
  19. order:[['id','DESC']],
  20. limit:pageSize,
  21. offset
  22. }
  23. if(query.title){
  24. condition.where = {
  25. title:{
  26. [Op.like]:`%${query.title}%`
  27. }
  28. }
  29. }
  30. const {count ,rows} = await Article.findAndCountAll(condition)
  31. res.json({
  32. status:true,
  33. message:'成功',
  34. data:{
  35. articles:rows,
  36. pagination:{
  37. total:count,
  38. currentPage,
  39. pageSize
  40. }
  41. }
  42. });
  43. }catch(error){
  44. res.status(500).json({
  45. status:false,
  46. message:'失败',
  47. errors:[error.message]
  48. });
  49. }
  50. });
  51. /*
  52. 查询文章详情
  53. GET /admin/articles/:id
  54. */
  55. router.get('/:id', async function(req, res, next) {
  56. try {
  57. //获取文章id
  58. const {id} = req.params
  59. //查询文章
  60. const article = await Article.findByPk(id)
  61. if(article){
  62. res.json({
  63. status:true,
  64. message:'成功',
  65. data:article
  66. });
  67. }else{
  68. res.status(404).json({
  69. status:false,
  70. message:'文章未找到',
  71. });
  72. }
  73. }catch(error){
  74. res.status(500).json({
  75. status:false,
  76. message:'失败',
  77. errors:[error.message]
  78. });
  79. }
  80. });
  81. /*
  82. 创建文章
  83. POST /admin/articles/
  84. */
  85. router.post('/', async function(req, res, next) {
  86. try {
  87. //白名单过滤
  88. const body = filterBody(req)
  89. // 添加调试日志
  90. console.log('创建文章请求体大小:', JSON.stringify(body).length);
  91. console.log('Content字段长度:', body.content ? body.content.length : 0);
  92. const article = await Article.create(body)
  93. res.status(201).json({
  94. status:true,
  95. message:'成功',
  96. data:article
  97. });
  98. }catch(error){
  99. // 添加详细的错误日志
  100. console.error('创建文章错误:', error);
  101. console.error('错误堆栈:', error.stack);
  102. console.error('请求体:', JSON.stringify(req.body, null, 2));
  103. if(error.name === 'SequelizeValidationError'){
  104. const errors = error.errors.map(e =>e.message)
  105. res.status(400).json({
  106. status:false,
  107. message:'请求参数错误',
  108. errors
  109. });
  110. }else if(error.name === 'SequelizeDatabaseError'){
  111. res.status(500).json({
  112. status:false,
  113. message:'数据库错误',
  114. errors:[error.message]
  115. });
  116. }else if(error.name === 'SequelizeConnectionError'){
  117. res.status(500).json({
  118. status:false,
  119. message:'数据库连接错误',
  120. errors:[error.message]
  121. });
  122. }else{
  123. res.status(500).json({
  124. status:false,
  125. message:'服务器内部错误',
  126. errors:[error.message]
  127. });
  128. }
  129. }
  130. });
  131. /*
  132. 删除文章
  133. GET /admin/articles/:id
  134. */
  135. router.delete('/:id', async function(req, res, next) {
  136. try {
  137. //获取文章id
  138. const {id} = req.params
  139. //查询文章
  140. const article = await Article.findByPk(id)
  141. if(article){
  142. await article.destroy()
  143. res.json({
  144. status:true,
  145. message:'成功',
  146. });
  147. }else{
  148. res.status(404).json({
  149. status:false,
  150. message:'文章未找到',
  151. });
  152. }
  153. }catch(error){
  154. res.status(500).json({
  155. status:false,
  156. message:'失败',
  157. errors:[error.message]
  158. });
  159. }
  160. });
  161. /*
  162. 更新文章
  163. GET /admin/articles/:id
  164. */
  165. router.put('/:id', async function(req, res, next) {
  166. try {
  167. //获取文章id
  168. const {id} = req.params
  169. //查询文章
  170. const article = await Article.findByPk(id)
  171. //白名单过滤
  172. const body = filterBody(req)
  173. if(article){
  174. await article.update(body)
  175. res.json({
  176. status:true,
  177. message:'成功',
  178. data:article
  179. });
  180. }else{
  181. res.status(404).json({
  182. status:false,
  183. message:'文章未找到',
  184. });
  185. }
  186. }catch(error){
  187. res.status(500).json({
  188. status:false,
  189. message:'失败',
  190. errors:[error.message]
  191. });
  192. }
  193. });
  194. function filterBody(req){
  195. // 数据清理和验证
  196. const body = {
  197. title: req.body.title ? String(req.body.title).trim() : null,
  198. content: req.body.content ? String(req.body.content) : null,
  199. type: req.body.type ? parseInt(req.body.type) : null,
  200. img: req.body.img ? String(req.body.img).trim() : null,
  201. date: req.body.date ? new Date(req.body.date) : null,
  202. author: req.body.author ? String(req.body.author).trim() : null,
  203. category: req.body.category ? parseInt(req.body.category) : null,
  204. crop: req.body.crop ? parseInt(req.body.crop) : null,
  205. seoKeyword: req.body.seoKeyword ? String(req.body.seoKeyword).trim() : null,
  206. seoDescription: req.body.seoDescription ? String(req.body.seoDescription).trim() : null
  207. };
  208. // 验证必填字段
  209. if (!body.title) {
  210. throw new Error('标题不能为空');
  211. }
  212. if (!body.content) {
  213. throw new Error('内容不能为空');
  214. }
  215. // 验证标题长度
  216. if (body.title.length > 255) {
  217. throw new Error('标题长度不能超过255个字符');
  218. }
  219. return body;
  220. }
  221. module.exports = router;