shaogen1995 1 месяц назад
Родитель
Сommit
67e353e61a

+ 100 - 1
src/controller/issueController.ts

@@ -1,5 +1,5 @@
 import dayjs from 'dayjs';
-import { Dict, Video } from '../model/index.js';
+import { Dict, Goods, Video } from '../model/index.js';
 import resSend from '../util/resSend.js';
 import { passWordJia } from '../util/pass.js';
 
@@ -123,6 +123,105 @@ const issue = {
     req.apiDescription = `内容发布-获取视频展示详情-${info.name}`;
     return resSend(res, 0, '获取视频展示详情成功', info);
   },
+  getGoodsList: async (req: any, res: any) => {
+    req.apiDescription = '内容发布-获取展品展示列表';
+    const { pageNum = 1, pageSize = 10, searchKey = '' } = req.body;
+
+    // 构建查询条件
+    const query: any = {};
+
+    if (searchKey) {
+      // 使用正则表达式实现模糊查询,'i'表示不区分大小写
+      query.name = { $regex: searchKey, $options: 'i' };
+    }
+
+    // 计算跳过的文档数量
+    const skip = (pageNum - 1) * pageSize;
+
+    // 修改排序逻辑:先按sort字段降序,再按updateTime字段降序
+    const sortCondition: any = { sort: -1, updateTime: -1 };
+
+    // 并行执行:获取总条数和查询当前页数据
+    const [total, data] = await Promise.all([
+      // 获取满足条件的总记录数
+      Goods.countDocuments(query),
+      // 查询当前页数据
+      Goods.find(query).skip(skip).limit(parseInt(pageSize)).sort(sortCondition), // 按sort字段降序,数字越大越靠前;相同则按updateTime降序
+    ]);
+
+    // 计算总页数
+    const totalPages = Math.ceil(total / pageSize);
+    return resSend(res, 0, '获取展品展示列表成功', {
+      list: data,
+      pageNum: parseInt(pageNum),
+      pageSize: parseInt(pageSize),
+      total,
+      totalPages,
+    });
+  },
+  saveGoods: async (req: any, res: any) => {
+    if (req.body._id) {
+      // 编辑展品展示
+      // 检查数据是否存在
+      const existing: any = await Goods.findById(req.body._id);
+      if (!existing) return resSend(res, 404, '数据不存在');
+
+      const fileType: string[] = req.body.fileType || [];
+
+      if (typeof fileType !== 'object' || fileType.length < 1)
+        return resSend(res, 404, '请选择文件类型');
+
+      // 更新字段
+      // 过滤一些字段
+      const filetStr: string[] = [];
+
+      Object.keys(req.body).forEach((key) => {
+        if (key !== '_id' && req.body[key] !== undefined) {
+          if (!filetStr.includes(key)) {
+            existing[key] = req.body[key];
+          }
+        }
+      });
+
+      existing.updateTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
+      const updatedUser = await existing.save();
+
+      const findObj = updatedUser.toObject();
+      req.apiDescription = `内容发布-编辑展品展示-${findObj.name}`;
+      return resSend(res, 0, '编辑展品展示成功', findObj);
+    } else {
+      const userModel = new Goods(req.body);
+      // 新增展品展示
+      // 保存数据到数据库
+      const dbBack = await userModel.save();
+      // 将文档转换为普通对象
+      const findObj = dbBack.toObject();
+      req.apiDescription = `内容发布-新增展品展示-${findObj.name}`;
+      return resSend(res, 0, '新增展品展示成功', findObj);
+    }
+  },
+  delGoods: async (req: any, res: any) => {
+    const { _id } = req.params; // 从URL参数中获取ID
+    // 1. 根据ID查找数据
+    const info = await Goods.findById(_id);
+    if (!info) return resSend(res, 404, '_id错误或数据已被删除');
+
+    const deletedInfo: any = await Goods.findByIdAndDelete(_id);
+    req.apiDescription = `内容发布-删除展品展示数据-${deletedInfo.name}`;
+    return resSend(res, 0, '删除展品展示数据成功');
+  },
+  getGoodsInfo: async (req: any, res: any) => {
+    const { _id } = req.params;
+
+    if (!_id) return resSend(res, 400, '_id不能为空');
+
+    // 根据ID查询信息
+    const info = await Goods.findById(_id);
+
+    if (!info) return resSend(res, 404, '_id错误或数据已被删除');
+    req.apiDescription = `内容发布-获取展品展示详情-${info.name}`;
+    return resSend(res, 0, '获取展品展示详情成功', info);
+  },
 };
 
 export default issue;

+ 14 - 0
src/middleware/validator/issueValidator.ts

@@ -15,3 +15,17 @@ export const addVideoVali = errorBack([
   body('videoUrl').notEmpty().withMessage('视频地址不能为空'),
   body('videoName').notEmpty().withMessage('视频名称不能为空'),
 ]);
+
+// 新增/编辑展品展示
+export const addGoodsVali = errorBack([
+  body('name')
+    .notEmpty()
+    .withMessage('标题不能为空')
+    .bail()
+    .isLength({ max: 30 })
+    .withMessage('长度最大为30个字符'),
+  body('releaseDate').notEmpty().withMessage('发布日期不能为空'),
+  body('type').notEmpty().withMessage('类别不能为空'),
+  body('cover').notEmpty().withMessage('封面地址不能为空'),
+  body('description').notEmpty().withMessage('概述不能为空'),
+]);

+ 63 - 0
src/model/goodsModel.ts

@@ -0,0 +1,63 @@
+import dayjs from 'dayjs';
+import mongoose from 'mongoose';
+
+const GoodsSchema = new mongoose.Schema({
+  // 标题
+  name: {
+    type: String,
+    require: true,
+  },
+  // 发布日期
+  releaseDate: {
+    type: String,
+    require: true,
+  },
+  // 类别
+  type: {
+    type: String,
+    require: true,
+  },
+  // 封面图地址(原图)
+  cover: {
+    type: String,
+    require: true,
+  },
+  // 封面图地址(压缩)
+  coverSmall: {
+    type: String,
+    default: '',
+  },
+  // 概述
+  description: {
+    type: String,
+    default: '',
+  },
+  // 文件类型
+  fileType: {
+    type: [String],
+    default: [],
+  },
+  // 多张图片id集合
+  fileIds: {
+    type: [Number],
+    default: [],
+  },
+  // 模型链接地址
+  modelLink: String,
+
+  // 排序值
+  sort: {
+    type: Number,
+    default: 999,
+  },
+  createTime: {
+    type: String,
+    default: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+  },
+  updateTime: {
+    type: String,
+    default: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+  },
+});
+
+export default GoodsSchema;

+ 2 - 0
src/model/index.ts

@@ -5,6 +5,7 @@ import { mongodbUrl } from '../config/config.default.js';
 import dictModel from './dictModel.js';
 import fileModel from './fileModel.js';
 import VideoSchema from './videlModel.js';
+import GoodsSchema from './goodsModel.js';
 
 const main = async () => {
   await mongoose.connect(mongodbUrl);
@@ -23,3 +24,4 @@ export const Log = mongoose.model('Log', logSchema);
 export const Dict = mongoose.model('Dict', dictModel);
 export const Files = mongoose.model('File', fileModel);
 export const Video = mongoose.model('video', VideoSchema);
+export const Goods = mongoose.model('goods', GoodsSchema);

+ 12 - 2
src/router/issue.ts

@@ -5,7 +5,7 @@ import { verifyToken } from '../middleware/jwt.js';
 // 记录日志的中间件
 import requestLogger from '../middleware/requestLogger.js';
 //  校验字段的中间件
-import { addVideoVali } from '../middleware/validator/issueValidator.js';
+import { addGoodsVali, addVideoVali } from '../middleware/validator/issueValidator.js';
 
 const issueRouter = express.Router();
 
@@ -14,6 +14,7 @@ issueRouter
   .get('/getIntro', verifyToken, issue.getIntro)
   // 编辑项目简介
   .post('/setIntro', verifyToken, requestLogger, issue.setIntro)
+  // ----------------------------------
   // 获取视频展示列表
   .post('/getVideoList', verifyToken, issue.getVideoList)
   // 新增/编辑视频展示列表
@@ -21,6 +22,15 @@ issueRouter
   // 删除视频展示
   .get('/delVideo/:_id', verifyToken, requestLogger, issue.delVideo)
   // 通过id获取视频展示详情
-  .get('/getVideoInfo/:_id', verifyToken, issue.getVideoInfo);
+  .get('/getVideoInfo/:_id', verifyToken, issue.getVideoInfo)
+  // ----------------------------------
+  // 获取展品展示列表
+  .post('/getGoodsList', verifyToken, issue.getGoodsList)
+  // 新增/编辑展品展示列表
+  .post('/saveGoods', verifyToken, addGoodsVali, requestLogger, issue.saveGoods)
+  // 删除展品展示
+  .get('/delGoods/:_id', verifyToken, requestLogger, issue.delGoods)
+  // 通过id获取展品展示详情
+  .get('/getGoodsInfo/:_id', verifyToken, issue.getGoodsInfo);
 
 export default issueRouter;

+ 7 - 1
src/router/show.ts

@@ -6,11 +6,17 @@ const showRouter = express.Router();
 showRouter
   // 获取所有接口的凭证
   .get('/getProof', issue.getProof)
+  // ----------------------------------
   // 获取项目简介
   .get('/getIntro', issue.getIntro)
+  // ----------------------------------
   // 获取视频展示列表
   .post('/getVideoList', issue.getVideoList)
   // 通过id获取视频展示详情
-  .get('/getVideoInfo/:_id', issue.getVideoInfo);
+  .get('/getVideoInfo/:_id', issue.getVideoInfo)
+  // ----------------------------------
+  // 获取展品展示列表
+  .post('/getGoodsList', issue.getGoodsList)
+  .get('/getGoodsInfo/:_id', issue.getGoodsInfo);
 
 export default showRouter;