Files
fjeei-nodejs/README.md
2025-10-27 17:58:38 +08:00

9.6 KiB
Raw Permalink Blame History

Fjeei Node.js API

快速开始

  1. 安装依赖

    • npm install
  2. 配置环境

    • 复制 .env.example.env
    • 按需填写 MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE
  3. 运行服务

    • 开发启动:npm run dev
    • 生产启动:npm start
  4. 测试接口

    • 健康检查:GET http://localhost:3000/api/health
    • 数据库连接测试:GET http://localhost:3000/api/db/ping
    • 新增文章:POST http://localhost:3000/api/articles
    • 获取文章详情:GET http://localhost:3000/api/articles/:id
    • 获取文章列表:GET http://localhost:3000/api/articles?isPublished=1&page=1&pageSize=20
    • 新增/更新视频:POST http://localhost:3000/api/videos/:idnew0 为新建)
    • 获取视频详情:GET http://localhost:3000/api/videos/:id
    • 获取视频列表:GET http://localhost:3000/api/videos?page=1&pageSize=10
    • 新增/更新文件:POST http://localhost:3000/api/files/:idnew0 为新建)
    • 获取文件详情:GET http://localhost:3000/api/files/:id
    • 获取文件列表:GET http://localhost:3000/api/files?page=1&pageSize=10
    • 精准服务新增/更新:POST http://localhost:3000/api/precision-services/:idnew0 为新建)
    • 精准服务详情:GET http://localhost:3000/api/precision-services/:id
    • 精准服务列表:GET http://localhost:3000/api/precision-services?page=1&pageSize=10
    • 单文件上传:POST http://localhost:3000/api/upload(字段名 file
    • 批量上传:POST http://localhost:3000/api/uploads(字段名 files

说明

  • 使用 mysql2/promise 创建连接池,接口内执行轻量查询 SELECT 1 AS ok 测试连接。
  • .env 未设置数据库,某些 MySQL 实例仍允许执行该查询;建议配置具体数据库以避免权限问题。
  • 生产环境下错误信息不显示具体细节,开发环境会返回错误信息以便排查。

中文变问号排查

  • 现象:保存/查询中文变成 ?
  • 原因:连接或表/库字符集不是 utf8mb4(常见为 latin1)。
  • 解决:
    1. 连接设置:本项目已在 src/db.js 中设置 charset: 'utf8mb4'
    2. 表/库设置:执行 sql/charset_fix.sql(将 your_database 替换为实际库名),把数据库与 articles 表转换为 utf8mb4
    3. 已经保存为问号的数据无法自动恢复,需要重新写入原始中文内容。

文章接口说明

  • 新增文章(传输字段为文章表所有字段)

    • POST /api/articles/
    • BodyJSON示例
      {
        "title": "示例标题",
        "titleColor": "#ff0000",
        "source": "新华社",
        "author": "张三",
        "url": "https://example.com/article/123",
        "publishTime": "2025-10-15T10:00:00Z",
        "content": "正文内容...",
        "summary": "摘要...",
        "coverImage": "https://example.com/cover.jpg",
        "sortNumber": 10,
        "viewCount": 0,
        "isPublished": 1,
        "isTop": 0,
        "isRecommended": 1,
        "isHot": 0,
        "isSlideshow": 0,
        "seoTitle": "SEO 标题",
        "seoKeywords": "关键字1,关键字2",
        "seoDescription": "SEO 描述"
      }
      
    • 返回:{ "success": true, "id": <新文章ID> }
  • 获取文章详情

    • GET /api/articles/:id
    • 返回:{ "success": true, "data": { id, title, ... } }
  • 获取文章列表(可选)

    • GET /api/articles?isPublished=1&page=1&pageSize=20
    • 返回:{ "success": true, "page": 1, "pageSize": 20, "data": [ ... ] }
  • 上架多篇文章

    • POST /api/articles/publish
    • BodyJSON示例
      {
        "ids": [1, 2, 3]
      }
      
    • 返回:{ "success": true, "message": "文章上架成功" }
  • 下架多篇文章

    • POST /api/articles/unpublish
    • BodyJSON示例
      {
        "ids": [1, 2, 3]
      }
      
    • 返回:{ "success": true, "message": "文章下架成功" }

视频接口说明

  • 新建或更新视频
    • POST /api/videos/:id
    • :idnew0 时创建,否则更新对应 ID
    • BodyJSON示例
      {
        "title": "示例视频",
        "titleColor": "#000000",
        "url": "https://example.com/page",
        "author": "张三",
        "publishTime": "2025-10-15T10:00:00Z",
        "content": "简介...",
        "articleNumber": "VID-2025-001",
        "coverImage": "https://example.com/cover.jpg",
        "videoUrl": "https://example.com/video.mp4",
        "classification": "新闻",
        "duration": "03:20",
        "fileSize": "120MB",
        "sortOrder": 10,
        "viewCount": 0,
        "isDraft": 0,
        "isPublished": 1,
        "isTop": 0,
        "isRecommended": 0,
        "isHot": 0,
        "isSlideshow": 0,
        "seoTitle": "SEO 标题",
        "seoKeywords": "关键字1,关键字2",
        "seoDescription": "SEO 描述"
      }
      
  • 获取视频详情
    • GET /api/videos/:id
  • 获取视频列表
    • GET /api/videos?page=1&pageSize=10&title=示例&classification=新闻&isPublished=1
    • 支持筛选:title(模糊)、classificationarticleNumberisPublishedisTopisRecommendedisHotisSlideshowstartTimeendTimeisDeleted
  • 批量发布
    • POST /api/videos/publish
    • BodyJSON示例
      [1, 2, 3]
      
    • 返回:{ "success": true, "message": "成功发布 X 个视频" }
  • 批量取消发布
    • POST /api/videos/unpublish
    • BodyJSON示例
      [1, 2, 3]
      
    • 返回:{ "success": true, "message": "成功取消发布 X 个视频" }
  • 删除/恢复/物理删除
    • 逻辑删除:DELETE /api/videos/:id
    • 恢复:POST /api/videos/recover/:id
    • 物理删除:DELETE /api/videos/force/:id

文件接口说明

  • 新建或更新文件
    • POST /api/files/:id
    • :idnew0 时创建,否则更新对应 ID
    • BodyJSON示例字段可按需传入
      {
        "title": "资料标题",
        "titleColor": "#000000",
        "fileName": "资料.pdf",
        "attachmentUrl": "https://example.com/files/xxx.pdf",
        "fileSize": "3.5MB",
        "uploader": "管理员",
        "url": "https://example.com/page",
        "uploadTime": "2025-10-15T10:00:00Z",
        "publishTime": "2025-10-15T10:00:00Z",
        "description": "详细描述...",
        "displayImage": "https://example.com/cover.jpg",
        "sortNumber": 10,
        "viewCount": 0,
        "downloadCount": 0,
        "isDraft": 0,
        "isPublished": 1,
        "isTop": 0,
        "isRecommended": 0,
        "isHot": 0,
        "isSlideshow": 0,
        "seoTitle": "SEO 标题",
        "seoKeywords": "关键字1,关键字2",
        "seoDescription": "SEO 描述"
      }
      
  • 获取文件详情
    • GET /api/files/:id
  • 获取文件列表
    • GET /api/files?page=1&pageSize=10&title=资料&isPublished=1
    • 支持筛选:title(模糊)、uploaderisDraftisPublishedisTopisRecommendedisHotisSlideshowstartTimeendTimeisDeleted
  • 批量发布/取消发布
    • 发布:POST /api/files/publishBody 示例:[1,2,3]
    • 取消发布:POST /api/files/unpublishBody 示例:[1,2,3]
  • 删除/恢复/物理删除
    • 逻辑删除:DELETE /api/files/:id
    • 恢复:POST /api/files/recover/:id
    • 物理删除:DELETE /api/files/force/:id
  • 导出
    • GET /api/files/export?format=xlsx|csv|json&isPublished=1
    • 保留筛选条件导出;文件名自动按日期生成
  • 导入
    • POST /api/files/import
    • 表单字段:file(支持 .xlsx/.csv/.json
    • 最少字段要求:titleattachmentUrl
    • 返回:{ success, message, total, inserted, updated, errors }

精准服务接口说明

  • 新建或更新
    • POST /api/precision-services/:id
    • :idnew0 时创建,否则更新对应 ID
    • BodyJSON示例与前端表单一致
      {
        "name": "张三",
        "gender": 1,
        "phone": "13800000001",
        "birthDate": "1950-05-12",
        "nation": "汉族",
        "workStartDate": "1970-08-01",
        "partyJoinDate": "1978-06-15",
        "currentBenefit": "离休干部待遇",
        "retirementInfo": "原某单位科长",
        "selfCare": 2,
        "livingCondition": "与家人同住",
        "address": "北京市朝阳区XX路XX号",
        "contact": "李四",
        "contactPhone": "13900000002"
      }
      
  • 获取详情
    • GET /api/precision-services/:id
  • 获取列表
    • GET /api/precision-services?page=1&pageSize=10&name=张&gender=1&isDeleted=0
    • 支持筛选:name(模糊)、phone(模糊)、gendernationselfCareisDeleted
  • 删除/恢复/物理删除
    • 逻辑删除:DELETE /api/precision-services/:id
    • 恢复:POST /api/precision-services/recover/:id
    • 物理删除:DELETE /api/precision-services/force/:id
    • 备注:更新时间统一字段为 updateTime

上传接口说明

  • 单文件上传
    • POST /api/upload
    • 表单字段:file
    • 可选参数query 或 form
      • dir 上传子目录(仅允许 -_/a-zA-Z0-9
      • prefix 文件名前缀
      • keepName 是否保留原始文件名的一部分(默认 false
    • 返回示例:
      {
        "success": true,
        "url": "http://localhost:3000/upload/2025-10/xxxxxx.png",
        "path": "/upload/2025-10/xxxxxx.png",
        "filename": "xxxxxx.png",
        "originalName": "origin.png",
        "size": 12345,
        "mimeType": "image/png"
      }
      
  • 批量上传
    • POST /api/uploads
    • 表单字段:files
    • 返回:{ success: true, files: [{ url, path, filename, originalName, size, mimeType }, ...] }
    • 静态访问:/upload 路径下可直接访问已上传文件